home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / Source / term-source.lha / Emulation.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  53KB  |  3,383 lines

  1. /*
  2. **    Emulation.c
  3. **
  4. **    Terminal emulation (parsing and processing) routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.     /* Flag indicating whether the cursor has already been
  17.      * erased or not.
  18.      */
  19.  
  20. STATIC BOOL                    CursorEnabled,
  21.                             CursorInvisible;
  22.  
  23.     /* Cursor handling data. */
  24.  
  25. STATIC WORD                    LastCursorX = -1,
  26.                             LastCursorY = -1;
  27.  
  28. STATIC LONG                    DestX,DestY,XSize,FontByColumn;
  29.  
  30. STATIC BOOL                    CursorGhosted;
  31.  
  32.     /* Backup style. */
  33.  
  34. STATIC ULONG                StyleType = FS_NORMAL;
  35.  
  36.     /* Cursor backup data. */
  37.  
  38. STATIC struct CursorData    CursorBackup;
  39. STATIC BOOL                    CursorBackupValid;
  40.  
  41.     /* A couple of internally referenced variables. */
  42.  
  43. STATIC WORD                    CharsInBuffer,
  44.                             ScanStep;
  45. STATIC UBYTE                SaveBuffer[MAX_SCAN_SIZE + 1];
  46. STATIC STRPTR                Arnie;
  47.  
  48. STATIC BOOL                    PrintFormFeed,
  49.                             PrintFullScreen;
  50.  
  51.     /* UpdatePens(VOID):
  52.      *
  53.      *    Update colour and style.
  54.      */
  55.  
  56. VOID
  57. UpdatePens()
  58. {
  59.     LONG ForePen,BackPen,Attrs,TextFlags,Mask;
  60.  
  61.         /* Update the colour mask. */
  62.  
  63.     switch(Config->ScreenConfig->ColourMode)
  64.     {
  65.         case COLOUR_AMIGA:
  66.  
  67.             Mask = 3;
  68.  
  69.             break;
  70.  
  71.         case COLOUR_EIGHT:
  72.  
  73.             Mask = 7;
  74.  
  75.             break;
  76.  
  77.         case COLOUR_SIXTEEN:
  78.  
  79.             Mask = 15;
  80.  
  81.             break;
  82.  
  83.         case COLOUR_MONO:
  84.  
  85.             Mask = 1;
  86.  
  87.             break;
  88.     }
  89.  
  90.     if(Mask > DepthMask)
  91.         Mask = DepthMask;
  92.  
  93.         /* Convert the colours and the text attributes */
  94.  
  95.     ForePen    = PenTable[ForegroundPen];
  96.     BackPen    = PenTable[BackgroundPen];
  97.     Attrs    = TextAttributeTable[Attributes];
  98.  
  99.         /* Choose a sensible colour */
  100.  
  101.     if(ForePen > Mask)
  102.     {
  103.         if(BackPen > Mask)
  104.         {
  105.             if(BackPen <= ForePen)
  106.             {
  107.                 ForePen = GetPenIndex(SafeTextPen);
  108.                 BackPen = 0;
  109.             }
  110.             else
  111.             {
  112.                 ForePen = 0;
  113.                 BackPen = GetPenIndex(SafeTextPen);
  114.             }
  115.         }
  116.         else
  117.         {
  118.             if(GetPenIndex(SafeTextPen) == BackPen)
  119.                 ForePen = 0;
  120.             else
  121.                 ForePen = GetPenIndex(SafeTextPen);
  122.         }
  123.     }
  124.     else
  125.     {
  126.         if(BackPen > Mask)
  127.         {
  128.             if(!ForePen)
  129.                 BackPen = GetPenIndex(SafeTextPen);
  130.             else
  131.                 BackPen = 0;
  132.         }
  133.     }
  134.  
  135.         /* Take care of the text attributes */
  136.  
  137.     TextFlags = 0;
  138.  
  139.     if(Attrs & ATTR_UNDERLINE)
  140.         TextFlags |= FSF_UNDERLINED;
  141.  
  142.     if(Attributes & ATTR_HIGHLIGHT)
  143.     {
  144.         if(Config->ScreenConfig->ColourMode == COLOUR_SIXTEEN)
  145.             ForePen |= 8;
  146.         else
  147.             TextFlags |= FSF_BOLD;
  148.     }
  149.  
  150.     if((Attributes & ATTR_BLINK) && (Config->TerminalConfig->EmulationMode == EMULATION_ANSIVT100))
  151.     {
  152.         switch(Config->ScreenConfig->ColourMode)
  153.         {
  154.             case COLOUR_AMIGA:
  155.  
  156.                 ForePen = 3;
  157.  
  158.                 break;
  159.  
  160.             case COLOUR_EIGHT:
  161.  
  162.                 ForePen |= 8;
  163.  
  164.                 break;
  165.  
  166.             case COLOUR_SIXTEEN:
  167.  
  168.                 if(Screen && DepthMask > 15)
  169.                     ForePen |= 16;
  170.  
  171.                 break;
  172.  
  173.             case COLOUR_MONO:
  174.  
  175.                 ForePen = GetPenIndex(SafeTextPen);
  176.  
  177.                 break;
  178.         }
  179.     }
  180.  
  181.         /* Make sure that monochrome text renders properly */
  182.  
  183.     if(Config->ScreenConfig->ColourMode == COLOUR_MONO)
  184.     {
  185.             /* Out of bounds? */
  186.  
  187.         if(ForePen > 1)
  188.         {
  189.                 /* If it's #7 then it's white, else it's black */
  190.  
  191.             if(ForePen == 7)
  192.                 ForePen = GetPenIndex(SafeTextPen);
  193.             else
  194.                 ForePen = 0;
  195.         }
  196.  
  197.         if(BackPen > 1)
  198.         {
  199.             if(BackPen == 7)
  200.                 BackPen = GetPenIndex(SafeTextPen);
  201.             else
  202.                 BackPen = 0;
  203.         }
  204.  
  205.             /* Oops... the text should be readable */
  206.  
  207.         if(ForePen == BackPen)
  208.         {
  209.                 /* Inverse video? */
  210.  
  211.             if(BackPen)
  212.             {
  213.                 ForePen = 0;
  214.                 BackPen = GetPenIndex(SafeTextPen);
  215.             }
  216.             else
  217.             {
  218.                 ForePen = GetPenIndex(SafeTextPen);
  219.                 BackPen = 0;
  220.             }
  221.         }
  222.     }
  223.  
  224.     if(Attrs & ATTR_INVERSE)
  225.     {
  226.         LONG Help;
  227.  
  228.         Help    = ForePen;
  229.         ForePen    = BackPen;
  230.         BackPen    = Help;
  231.     }
  232.  
  233.     if(TextFlags != StyleType)
  234.     {
  235.         SetSoftStyle(RPort,TextFlags,~0);
  236.  
  237.         StyleType = TextFlags;
  238.     }
  239.  
  240.     FgPen = MappedPens[0][ForePen];
  241.     BgPen = MappedPens[0][BackPen];
  242.  
  243.     if(FgPen != ReadAPen(RPort))
  244.         SetAPen(RPort,FgPen);
  245.  
  246.     if(BgPen != ReadBPen(RPort))
  247.         SetBPen(RPort,BgPen);
  248. }
  249.  
  250.     /* GetFontWidth():
  251.      *
  252.      *    Get the font width of the current line.
  253.      */
  254.  
  255. LONG
  256. GetFontWidth()
  257. {
  258.     if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  259.     {
  260.         if(CurrentCharWidth == SCALE_HALF)
  261.             return((LONG)(TextFontWidth / 2));
  262.         else
  263.             return(TextFontWidth);
  264.     }
  265.     else
  266.     {
  267.         if(CurrentCharWidth == SCALE_HALF)
  268.             return(TextFontWidth);
  269.         else
  270.             return((LONG)(TextFontWidth * 2));
  271.     }
  272. }
  273.  
  274.     /* RethinkRasterLimit():
  275.      *
  276.      *    Take care of the extreme left column position
  277.      *    permitted.
  278.      */
  279.  
  280. VOID
  281. RethinkRasterLimit()
  282. {
  283.     LONG Y;
  284.  
  285.     if(CursorY > LastLine)
  286.         Y = LastLine;
  287.     else
  288.     {
  289.         if(CursorY < 0)
  290.             Y = 0;
  291.         else
  292.             Y = CursorY;
  293.     }
  294.  
  295.     if(RasterAttr[Y] == SCALE_ATTR_NORMAL)
  296.     {
  297.         if(CurrentCharWidth == SCALE_HALF)
  298.             FontByColumn = (LastColumn + 1) * 2 - 1;
  299.         else
  300.             FontByColumn = LastColumn;
  301.     }
  302.     else
  303.     {
  304.         if(CurrentCharWidth == SCALE_HALF)
  305.             FontByColumn = LastColumn;
  306.         else
  307.             FontByColumn = ((LastColumn + 1) / 2) - 1;
  308.     }
  309. }
  310.  
  311.     /* ScrollRegion(LONG Direction):
  312.      *
  313.      *    Scroll the current scroll region up or down.
  314.      */
  315.  
  316. VOID
  317. ScrollRegion(LONG Direction)
  318. {
  319.     LONG RegionTop,RegionBottom,RegionLines;
  320.     LONG Dir,MinY,MaxY;
  321.  
  322.     if(Direction < 0)
  323.         Dir = -Direction;
  324.     else
  325.         Dir = Direction;
  326.  
  327.     if(RegionSet)
  328.     {
  329.         MinY             = MUL_Y(Top);
  330.         MaxY            = MUL_Y(Bottom + 1) - 1;
  331.  
  332.         RegionTop        = Top;
  333.         RegionBottom    = Bottom + 1;
  334.         RegionLines        = Bottom - Top + 1;
  335.     }
  336.     else
  337.     {
  338.         MinY            = 0;
  339.         MaxY             = MUL_Y(LastLine + 1) - 1;
  340.  
  341.         RegionTop        = 0;
  342.         RegionBottom    = LastLine + 1;
  343.         RegionLines        = LastLine + 1;
  344.     }
  345.  
  346.     BackupRender();
  347.  
  348.     RasterScrollRegion(Direction,RegionTop,RegionBottom,RegionLines);
  349.  
  350.     if(Config->EmulationConfig->ScrollMode == SCROLL_JUMP)
  351.     {
  352.         if(Dir > RegionLines)
  353.             ScrollLineRectFill(RPort,0,MinY,LastPixel,MaxY);
  354.         else
  355.         {
  356.             if(Direction > 0)
  357.                 ScrollLineRaster(RPort,0,MUL_Y(Direction),0,MinY,LastPixel,MaxY,FALSE);
  358.             else
  359.                 ScrollLineRaster(RPort,0,-MUL_Y(-Direction),0,MinY,LastPixel,MaxY,FALSE);
  360.         }
  361.     }
  362.     else
  363.     {
  364.         if(Dir > RegionLines)
  365.         {
  366.             if(Direction > 0)
  367.                 Direction = RegionLines;
  368.             else
  369.                 Direction = -RegionLines;
  370.         }
  371.  
  372.         if(Direction > 0)
  373.             ScrollLineRaster(RPort,0,MUL_Y(Direction),0,MinY,LastPixel,MaxY,TRUE);
  374.         else
  375.             ScrollLineRaster(RPort,0,-MUL_Y(-Direction),0,MinY,LastPixel,MaxY,TRUE);
  376.     }
  377.  
  378.     BackupRender();
  379. }
  380.  
  381.     /* LastChar(STRPTR Buffer):
  382.      *
  383.      *    Return the last character in a string.
  384.      */
  385.  
  386. STATIC UBYTE
  387. LastChar(STRPTR Buffer)
  388. {
  389.     LONG Offset = 0;
  390.  
  391.     while(Buffer[Offset])
  392.         Offset++;
  393.  
  394.     return(Buffer[Offset - 1]);
  395. }
  396.  
  397.     /* ReadValue(STRPTR Buffer,BYTE *Value):
  398.      *
  399.      *    Parse a buffer for numbers and return a pointer
  400.      *    to the next buffer element to contain additional
  401.      *    information.
  402.      */
  403.  
  404. STATIC STRPTR
  405. ReadValue(STRPTR Buffer,WORD *Value)
  406. {
  407.     while(*Buffer && *Buffer != ';' && (*Buffer < '0' || *Buffer > '9'))
  408.         Buffer++;
  409.  
  410.     if(*Buffer)
  411.     {
  412.         *Value = 0;
  413.  
  414.         while(*Buffer >= '0' && *Buffer <= '9')
  415.             *Value = (*Value * 10) + (*Buffer++ - '0');
  416.     }
  417.     else
  418.         *Value = -1;
  419.  
  420.     if(*Buffer == ';' || *Buffer == ' ')
  421.         return(Buffer + 1);
  422.     else
  423.         return(NULL);
  424. }
  425.  
  426.     /* EmulationSerWrite(STRPTR String,LONG Length):
  427.      *
  428.      *    Write text to the serial line.
  429.      */
  430.  
  431. STATIC VOID
  432. EmulationSerWrite(STRPTR String,LONG Length)
  433. {
  434.     if(FindTask(NULL) == SpecialQueue->SigTask)
  435.         SerWrite(String,Length);
  436.     else
  437.     {
  438.         struct DataMsg *Msg;
  439.  
  440.         if(Length == -1)
  441.             Length = strlen(String);
  442.  
  443.         if(Msg = (struct DataMsg *)CreateMsgItem(sizeof(struct DataMsg) + Length + 1))
  444.         {
  445.             Msg->Type = DATAMSGTYPE_WRITE;
  446.             Msg->Data = (STRPTR)(Msg + 1);
  447.             Msg->Size = Length;
  448.  
  449.             CopyMem(String,Msg->Data,Length + 1);
  450.  
  451.             PutMsgItem(SpecialQueue,(struct MsgItem *)Msg);
  452.         }
  453.     }
  454. }
  455.  
  456.     /* RethinkCursorPosition():
  457.      *
  458.      *    Calculate the new cursor position.
  459.      */
  460.  
  461. STATIC VOID
  462. RethinkCursorPosition(VOID)
  463. {
  464.     if(CursorY != LastCursorY || CursorX != LastCursorX)
  465.     {
  466.         STATIC LONG X,Y;
  467.  
  468.         if(CursorY != LastCursorY)
  469.         {
  470.             if(CursorY > LastLine)
  471.                 Y = LastLine;
  472.             else
  473.             {
  474.                 if(CursorY < 0)
  475.                     Y = 0;
  476.                 else
  477.                     Y = CursorY;
  478.             }
  479.  
  480.             if(RasterAttr[Y] == SCALE_ATTR_NORMAL)
  481.             {
  482.                 if(CurrentCharWidth == SCALE_HALF)
  483.                     FontByColumn = ((LastColumn + 1) * 2) - 1;
  484.                 else
  485.                     FontByColumn = LastColumn;
  486.             }
  487.             else
  488.             {
  489.                 if(CurrentCharWidth == SCALE_HALF)
  490.                     FontByColumn = LastColumn;
  491.                 else
  492.                     FontByColumn = ((LastColumn + 1) / 2) - 1;
  493.             }
  494.  
  495.             DestY = MUL_Y(Y);
  496.  
  497.             LastCursorY = CursorY;
  498.         }
  499.  
  500.         LastCursorX = CursorX;
  501.  
  502.         if(CursorX > FontByColumn)
  503.             X = FontByColumn;
  504.         else
  505.         {
  506.             if(CursorX < 0)
  507.                 X = 0;
  508.             else
  509.                 X = CursorX;
  510.         }
  511.  
  512.         if(CurrentCharWidth == SCALE_NORMAL)
  513.         {
  514.             if(RasterAttr[Y] == SCALE_ATTR_NORMAL)
  515.             {
  516.                     /* Normal width */
  517.  
  518.                 DestX = MUL_X(X);
  519.                 XSize = TextFontWidth;
  520.             }
  521.             else
  522.             {
  523.                     /* Double width */
  524.  
  525.                 DestX = MUL_X(X) * 2;
  526.                 XSize = TextFontWidth * 2;
  527.             }
  528.         }
  529.         else
  530.         {
  531.             if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  532.             {
  533.                     /* Half width */
  534.  
  535.                 DestX = MUL_X(X) / 2;
  536.                 XSize = TextFontWidth / 2;
  537.             }
  538.             else
  539.             {
  540.                     /* Twice the half width */
  541.  
  542.                 DestX = MUL_X(X);
  543.                 XSize = TextFontWidth;
  544.             }
  545.         }
  546.     }
  547. }
  548.  
  549.     /* ToggleCursor():
  550.      *
  551.      *    (Re)draw the cursor image.
  552.      */
  553.  
  554. STATIC VOID
  555. ToggleCursor(VOID)
  556. {
  557.     if(Config->TerminalConfig->EmulationMode != EMULATION_EXTERNAL)
  558.     {
  559.         ULONG OldAPen,OldBPen,OldDrMd,OldMask;
  560.         LONG Left,Top;
  561.  
  562.         OldAPen    = ReadAPen(RPort);
  563.         OldBPen    = ReadBPen(RPort);
  564.         OldDrMd    = ReadDrMd(RPort);
  565.         OldMask = GetMask(RPort);
  566.  
  567.         Left    = WindowLeft + DestX;
  568.         Top        = WindowTop + DestY;
  569.  
  570.         SetPens(RPort,DepthMask,OldBPen,JAM1 | COMPLEMENT);
  571.         SetMask(RPort,DepthMask);
  572.         FillBox(RPort,Left,Top,XSize,TextFontHeight);
  573.         SetPens(RPort,OldAPen,OldBPen,OldDrMd);
  574.         SetMask(RPort,OldMask);
  575.     }
  576. }
  577.  
  578.     /* RedrawCursor():
  579.      *
  580.      *    Change the appearance of the cursor.
  581.      */
  582.  
  583. STATIC VOID
  584. RedrawCursor(VOID)
  585. {
  586.     ObtainSemaphore(&TerminalSemaphore);
  587.  
  588.     RethinkCursorPosition();
  589.  
  590.     if(CursorGhosted)
  591.     {
  592.         SetAfPt(RPort,(UWORD *)&Crosshatch,1);
  593.  
  594.         ToggleCursor();
  595.  
  596.         SetAfPt(RPort,NULL,0);
  597.     }
  598.     else
  599.         ToggleCursor();
  600.  
  601.     ReleaseSemaphore(&TerminalSemaphore);
  602. }
  603.  
  604.     /* DoCancel():
  605.      *
  606.      *    Cancel any currently scanned sequence.
  607.      */
  608.  
  609. BOOL
  610. DoCancel()
  611. {
  612.     InSequence        = FALSE;
  613.     CharsInBuffer    = 0;
  614.     ScanStep        = 0;
  615.  
  616.     return(FALSE);
  617. }
  618.  
  619.     /* ParseCode(LONG c):
  620.      *
  621.      *    Input:    A character to be passed through the ANSI code
  622.      *        parser.
  623.      *
  624.      *    Output:    FALSE if input characters did form a valid ANSI
  625.      *        control sequence or if input characters did not
  626.      *        form an ANSI control sequence at all.
  627.      *
  628.      *        TRUE if input characters did possibly introduce
  629.      *        a valid ANSI control sequence.
  630.      */
  631.  
  632. BOOL
  633. ParseCode(LONG c)
  634. {
  635.         /* ScanStep = 0:    This is the first character
  636.          *                    to introduce a control sequence.
  637.          */
  638.  
  639.     if(!ScanStep)
  640.     {
  641.         LONG i;
  642.  
  643.             /* Scan all available codes and try to find
  644.              * a match.
  645.              */
  646.  
  647.         for(i = 0 ; i < NumCodes ; i++)
  648.         {
  649.                 /* This character may introduce a
  650.                  * control sequence.
  651.                  */
  652.  
  653.             if(ANSICode[i].FirstChar == c)
  654.             {
  655.                     /* If this is a single
  656.                      * character control sequence
  657.                      * call the appropriate function
  658.                      * and exit immediately.
  659.                      */
  660.  
  661.                 if(ANSICode[i].ExactSize == 1)
  662.                 {
  663.                     if(Config->TerminalConfig->EmulationMode != EMULATION_ATOMIC)
  664.                     {
  665.                         SaveBuffer[CharsInBuffer++] = c;
  666.                         SaveBuffer[CharsInBuffer  ] = 0;
  667.  
  668.                         (*ANSICode[i].Func)(SaveBuffer);
  669.                     }
  670.  
  671.                     CharsInBuffer = ScanStep = 0;
  672.  
  673.                     return(FALSE);
  674.                 }
  675.                 else
  676.                 {
  677.                         /* The length of this control
  678.                          * sequence is greater than
  679.                          * a single character. Save
  680.                          * the input character and
  681.                          * return.
  682.                          */
  683.  
  684.                     ScanStep = i;
  685.  
  686.                     SaveBuffer[CharsInBuffer++] = c;
  687.  
  688.                         /* Where to stop. */
  689.  
  690.                     Arnie = ANSICode[i].Terminator;
  691.  
  692.                     return(TRUE);
  693.                 }
  694.             }
  695.         }
  696.     }
  697.     else
  698.     {
  699.         if(CharsInBuffer < MAX_SCAN_SIZE)
  700.         {
  701.             if(Arnie)
  702.             {
  703.                 LONG i;
  704.  
  705.                     /* Scan the remaining codes for a match. */
  706.  
  707.                 for(i = ScanStep ; i < NumCodes ; i++)
  708.                 {
  709.                         /* This sequence begins with the
  710.                          * same character the parser was
  711.                          * initialized with, so let's take
  712.                          * a look at it.
  713.                          */
  714.  
  715.                     if(ANSICode[i].FirstChar == SaveBuffer[0])
  716.                     {
  717.                             /* This character is supposed to
  718.                              * terminate the sequence, so exit.
  719.                              */
  720.  
  721.                         if(Arnie[c])
  722.                         {
  723.                             if(Config->TerminalConfig->EmulationMode != EMULATION_ATOMIC)
  724.                             {
  725.                                 SaveBuffer[CharsInBuffer++] = c;
  726.                                 SaveBuffer[CharsInBuffer  ] = 0;
  727.  
  728.                                 (*ANSICode[i].Func)(SaveBuffer);
  729.                             }
  730.  
  731.                             CharsInBuffer = ScanStep = 0;
  732.  
  733.                             Arnie = NULL;
  734.  
  735.                             return(FALSE);
  736.                         }
  737.                         else
  738.                         {
  739.                                 /* If this character is part of
  740.                                  * a legal sequence store it
  741.                                  * and return.
  742.                                  */
  743.  
  744.                             if(ANSICode[i].Match[c])
  745.                             {
  746.                                 ScanStep = i;
  747.  
  748.                                 SaveBuffer[CharsInBuffer++] = c;
  749.  
  750.                                 return(TRUE);
  751.                             }
  752.                         }
  753.                     }
  754.                 }
  755.             }
  756.             else
  757.             {
  758.                 LONG i;
  759.  
  760.                 for(i = ScanStep ; i < NumCodes ; i++)
  761.                 {
  762.                         /* This sequence begins with the
  763.                          * same character the parser was
  764.                          * initialized with, so let's take
  765.                          * a look at it.
  766.                          */
  767.  
  768.                     if(ANSICode[i].FirstChar == SaveBuffer[0])
  769.                     {
  770.                             /* This character is supposed to
  771.                              * terminate the sequence, so exit.
  772.                              */
  773.  
  774.                         if(ANSICode[i].LastChar == c || (!ANSICode[i].LastChar && CharsInBuffer == 2 && ANSICode[i].ExactSize == 3))    /* Special case for VT52 */
  775.                         {
  776.                             if(Config->TerminalConfig->EmulationMode != EMULATION_ATOMIC)
  777.                             {
  778.                                 SaveBuffer[CharsInBuffer++] = c;
  779.                                 SaveBuffer[CharsInBuffer  ] = 0;
  780.  
  781.                                 (*ANSICode[i].Func)(SaveBuffer);
  782.                             }
  783.  
  784.                             CharsInBuffer = ScanStep = 0;
  785.  
  786.                             return(FALSE);
  787.                         }
  788.                         else
  789.                         {
  790.                                 /* If this character is part of
  791.                                  * a legal sequence store it
  792.                                  * and return.
  793.                                  */
  794.  
  795.                             if(ANSICode[i].Match[c])
  796.                             {
  797.                                 ScanStep = i;
  798.  
  799.                                 SaveBuffer[CharsInBuffer++] = c;
  800.  
  801.                                 return(TRUE);
  802.                             }
  803.                         }
  804.                     }
  805.                 }
  806.             }
  807.         }
  808.     }
  809.  
  810.         /* Return failure. */
  811.  
  812.     CharsInBuffer = ScanStep = 0;
  813.  
  814.     Arnie = NULL;
  815.  
  816.     return(FALSE);
  817. }
  818.  
  819.     /* NormalCursor():
  820.      *
  821.      *    Enable normal (filled) cursor image.
  822.      */
  823.  
  824. VOID
  825. NormalCursor()
  826. {
  827.     ObtainSemaphore(&TerminalSemaphore);
  828.  
  829.     if(CursorGhosted)
  830.     {
  831.         if(CursorEnabled && !CursorInvisible)
  832.         {
  833.             SetAfPt(RPort,(UWORD *)&Crosshatch,1);
  834.  
  835.             ToggleCursor();
  836.  
  837.             SetAfPt(RPort,NULL,0);
  838.  
  839.             ToggleCursor();
  840.         }
  841.  
  842.         CursorGhosted = FALSE;
  843.     }
  844.  
  845.     ReleaseSemaphore(&TerminalSemaphore);
  846. }
  847.  
  848.     /* GhostCursor():
  849.      *
  850.      *    Enable ghosted (checkered) cursor image.
  851.      */
  852.  
  853. VOID
  854. GhostCursor()
  855. {
  856.     ObtainSemaphore(&TerminalSemaphore);
  857.  
  858.     if(!CursorGhosted)
  859.     {
  860.         if(CursorEnabled && !CursorInvisible)
  861.         {
  862.             ToggleCursor();
  863.  
  864.             SetAfPt(RPort,(UWORD *)&Crosshatch,1);
  865.  
  866.             ToggleCursor();
  867.  
  868.             SetAfPt(RPort,NULL,0);
  869.         }
  870.  
  871.         CursorGhosted = TRUE;
  872.     }
  873.  
  874.     ReleaseSemaphore(&TerminalSemaphore);
  875. }
  876.  
  877.     /* RepositionCursor():
  878.      *
  879.      *    Redraw the cursor at the new position.
  880.      */
  881.  
  882. VOID
  883. RepositionCursor()
  884. {
  885.     ObtainSemaphore(&TerminalSemaphore);
  886.  
  887.     RethinkCursorPosition();
  888.  
  889.     Move(RPort,WindowLeft + DestX,WindowTop + DestY + TextFontBase);
  890.  
  891.     ReleaseSemaphore(&TerminalSemaphore);
  892. }
  893.  
  894.     /* ClearCursor():
  895.      *
  896.      *    Clear the cursor image.
  897.      */
  898.  
  899. VOID
  900. ClearCursor()
  901. {
  902.     ObtainSemaphore(&TerminalSemaphore);
  903.  
  904.     if(CursorEnabled && !CursorInvisible)
  905.     {
  906.         RedrawCursor();
  907.  
  908.         CursorEnabled = FALSE;
  909.     }
  910.  
  911.     ReleaseSemaphore(&TerminalSemaphore);
  912. }
  913.  
  914.     /* DrawCursor():
  915.      *
  916.      *    Explicitely (re-)draw the cursor image.
  917.      */
  918.  
  919. VOID
  920. DrawCursor()
  921. {
  922.     ObtainSemaphore(&TerminalSemaphore);
  923.  
  924.     if(!CursorEnabled && !CursorInvisible)
  925.     {
  926.         RedrawCursor();
  927.  
  928.         CursorEnabled = TRUE;
  929.     }
  930.  
  931.     ReleaseSemaphore(&TerminalSemaphore);
  932. }
  933.  
  934.     /* BackupRender():
  935.      *
  936.      *    Save current draw modes, pen and position or restore
  937.      *    the data.
  938.      */
  939.  
  940. VOID
  941. BackupRender()
  942. {
  943.     STATIC BOOL        Called;
  944.     STATIC ULONG    DrMd,FgPen,BgPen;
  945.     STATIC UWORD    OldX,OldY;
  946.     STATIC UBYTE    Style;
  947.  
  948.     if(!Called)
  949.     {
  950.         DrMd    = ReadDrMd(RPort);
  951.         FgPen    = ReadAPen(RPort);
  952.         BgPen    = ReadBPen(RPort);
  953.  
  954.         OldX    = RPort->cp_x - WindowLeft;
  955.         OldY    = RPort->cp_y - WindowTop;
  956.  
  957.         Style    = StyleType;
  958.  
  959.         Called    = TRUE;
  960.     }
  961.     else
  962.     {
  963.         SetPens(RPort,FgPen,BgPen,DrMd);
  964.  
  965.         Move(RPort,OldX + WindowLeft,OldY + WindowTop);
  966.  
  967.         if(Style != StyleType)
  968.         {
  969.             SetSoftStyle(RPort,Style,~0);
  970.  
  971.             StyleType = Style;
  972.         }
  973.  
  974.         Called = FALSE;
  975.     }
  976. }
  977.  
  978.     /* ShiftChar(LONG Size):
  979.      *
  980.      *    Simulate character insertion at the current cursor
  981.      *    position by shifting the whole line Size times eight pixels
  982.      *    to the right.
  983.      */
  984.  
  985. VOID
  986. ShiftChar(LONG Size)
  987. {
  988.     LONG DeltaX,MinX,MinY;
  989.  
  990.     MinY = MUL_Y(CursorY);
  991.  
  992.     if(CurrentCharWidth == SCALE_NORMAL)
  993.     {
  994.         if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  995.         {
  996.             DeltaX    = MUL_X(Size);
  997.             MinX    = MUL_X(CursorX);
  998.         }
  999.         else
  1000.         {
  1001.             DeltaX    = MUL_X(Size) * 2;
  1002.             MinX    = MUL_X(CursorX) * 2;
  1003.         }
  1004.     }
  1005.     else
  1006.     {
  1007.         if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  1008.         {
  1009.             DeltaX    = MUL_X(Size) / 2;
  1010.             MinX    = MUL_X(CursorX) / 2;
  1011.         }
  1012.         else
  1013.         {
  1014.             DeltaX    = MUL_X(Size);
  1015.             MinX    = MUL_X(CursorX);
  1016.         }
  1017.     }
  1018.  
  1019.     if(MinX < WindowWidth)
  1020.     {
  1021.         BackupRender();
  1022.  
  1023.         ScrollLineRasterNoTabChange(RPort,-DeltaX,0,MinX,MinY,LastPixel,MinY + TextFontHeight - 1,FALSE);
  1024.  
  1025.         BackupRender();
  1026.     }
  1027. }
  1028.  
  1029.     /* Ignore():
  1030.      *
  1031.      *    Do nothing, return immediately.
  1032.      */
  1033.  
  1034. VOID
  1035. Ignore()
  1036. {
  1037. }
  1038.  
  1039.     /* ScrollDown(STRPTR Buffer):
  1040.      *
  1041.      *    Scroll the current region down.
  1042.      */
  1043.  
  1044. VOID
  1045. ScrollDown(STRPTR Buffer)
  1046. {
  1047.     WORD Value;
  1048.  
  1049.     ReadValue(Buffer,&Value);
  1050.  
  1051.     if(Value < 1)
  1052.         Value = 1;
  1053.  
  1054.     ScrollRegion(-Value);
  1055. }
  1056.  
  1057.     /* ScrollUp(STRPTR Buffer):
  1058.      *
  1059.      *    Scroll the current region up.
  1060.      */
  1061.  
  1062. VOID
  1063. ScrollUp(STRPTR Buffer)
  1064. {
  1065.     WORD Value;
  1066.  
  1067.     ReadValue(Buffer,&Value);
  1068.  
  1069.     if(Value < 1)
  1070.         Value = 1;
  1071.  
  1072.     ScrollRegion(Value);
  1073. }
  1074.  
  1075.     /* CursorScrollDown():
  1076.      *
  1077.      *    Move cursor down and scroll region if necessary.
  1078.      */
  1079.  
  1080. VOID
  1081. CursorScrollDown()
  1082. {
  1083.     DownLine();
  1084.  
  1085.     RepositionCursor();
  1086. }
  1087.  
  1088. VOID
  1089. DownLine()
  1090. {
  1091.     UBYTE InRegion;
  1092.     LONG Hit;
  1093.  
  1094.     InRegion = TRUE;
  1095.     Hit      = LastLine;
  1096.  
  1097.     if(RegionSet)
  1098.     {
  1099.         if(CursorY <= Bottom)
  1100.             Hit = Bottom;
  1101.         else
  1102.             InRegion = FALSE;
  1103.     }
  1104.  
  1105.     if(CursorY == Hit)
  1106.     {
  1107.         if(InRegion)
  1108.             ScrollRegion(1);
  1109.     }
  1110.     else
  1111.     {
  1112.         CursorY++;
  1113.  
  1114.         if(CursorY > LastLine)
  1115.             CursorY = LastLine;
  1116.  
  1117.         ConFontScaleUpdate();
  1118.     }
  1119. }
  1120.  
  1121.     /* CursorScrollUp():
  1122.      *
  1123.      *    Move cursor up and scroll region if necessary.
  1124.      */
  1125.  
  1126. VOID
  1127. CursorScrollUp()
  1128. {
  1129.     BOOL InRegion;
  1130.     LONG Hit;
  1131.  
  1132.     InRegion    = TRUE;
  1133.     Hit            = 0;
  1134.  
  1135.     if(RegionSet)
  1136.     {
  1137.         if(CursorY >= Top)
  1138.             Hit = Top;
  1139.         else
  1140.             InRegion = FALSE;
  1141.     }
  1142.  
  1143.     if(CursorY == Hit)
  1144.     {
  1145.         if(InRegion)
  1146.             ScrollRegion(-1);
  1147.     }
  1148.     else
  1149.     {
  1150.         if(--CursorY < 0)
  1151.             CursorY = 0;
  1152.  
  1153.         ConFontScaleUpdate();
  1154.     }
  1155.  
  1156.     RepositionCursor();
  1157. }
  1158.  
  1159.     /* NextLine():
  1160.      *
  1161.      *    Do something like CR+LF.
  1162.      */
  1163.  
  1164. VOID
  1165. NextLine()
  1166. {
  1167.     CursorX = 0;
  1168.  
  1169.     DownLine();
  1170.  
  1171.     RepositionCursor();
  1172. }
  1173.  
  1174.     /* SaveCursor():
  1175.      *
  1176.      *    Save cursor position and rendering attributes.
  1177.      */
  1178.  
  1179. VOID
  1180. SaveCursor()
  1181. {
  1182.     CursorBackup.Charset        = Charset;
  1183.     CursorBackup.Attributes        = Attributes;
  1184.     CursorBackup.CursorX        = CursorX;
  1185.     CursorBackup.CursorY        = CursorY;
  1186.     CursorBackup.Style            = StyleType;
  1187.     CursorBackup.FgPen            = ForegroundPen;
  1188.     CursorBackup.BgPen            = BackgroundPen;
  1189.     CursorBackup.CurrentFont    = CurrentFont;
  1190.     CursorBackup.CharMode[0]    = CharMode[0];
  1191.     CursorBackup.CharMode[1]    = CharMode[1];
  1192.  
  1193.     CursorBackupValid = TRUE;
  1194. }
  1195.  
  1196.     /* FontStuff(STRPTR Buffer):
  1197.      *
  1198.      *    Set the drawing font (standard characters/line).
  1199.      */
  1200.  
  1201. VOID
  1202. FontStuff(STRPTR Buffer)
  1203. {
  1204.     BOOL Changed;
  1205.  
  1206.     Changed = FALSE;
  1207.  
  1208.     if(Buffer[0] == '(')
  1209.     {
  1210.         switch(LastChar(Buffer))
  1211.         {
  1212.             case 'A':
  1213.             case 'B':
  1214.  
  1215.                 if(CharMode[0] != TABLE_ASCII && !Charset)
  1216.                     Changed = TRUE;
  1217.  
  1218.                 CharMode[0] = TABLE_ASCII;
  1219.  
  1220.                 break;
  1221.  
  1222.             case '0':
  1223.  
  1224.                 if(CharMode[0] != TABLE_GFX && !Charset)
  1225.                     Changed = TRUE;
  1226.  
  1227.                 CharMode[0] = TABLE_GFX;
  1228.  
  1229.                 break;
  1230.         }
  1231.     }
  1232.  
  1233.     if(Buffer[0] == ')')
  1234.     {
  1235.         switch(LastChar(Buffer))
  1236.         {
  1237.             case 'A':
  1238.             case 'B':
  1239.  
  1240.                 if(CharMode[1] != TABLE_ASCII && Charset == 1)
  1241.                     Changed = TRUE;
  1242.  
  1243.                 CharMode[1] = TABLE_ASCII;
  1244.  
  1245.                 break;
  1246.  
  1247.             case '0':
  1248.  
  1249.                 if(CharMode[1] != TABLE_GFX && Charset == 1)
  1250.                     Changed = TRUE;
  1251.  
  1252.                 CharMode[1] = TABLE_GFX;
  1253.  
  1254.                 break;
  1255.         }
  1256.     }
  1257.  
  1258.     if(Changed)
  1259.     {
  1260.         BackupRender();
  1261.  
  1262.         if(Charset)
  1263.             DoShiftIn();
  1264.         else
  1265.             DoShiftOut();
  1266.  
  1267.         BackupRender();
  1268.     }
  1269. }
  1270.  
  1271.     /* LoadCursor():
  1272.      *
  1273.      *    Load cursor position and rendering attributes.
  1274.      */
  1275.  
  1276. VOID
  1277. LoadCursor()
  1278. {
  1279.     Charset        = CursorBackup.Charset;
  1280.  
  1281.     CharMode[0]    = CursorBackup.CharMode[0];
  1282.     CharMode[1]    = CursorBackup.CharMode[1];
  1283.  
  1284.     if(CurrentFont != CursorBackup.CurrentFont)
  1285.     {
  1286.         CurrentFont = CursorBackup.CurrentFont;
  1287.  
  1288.         SetFont(RPort,CurrentFont);
  1289.  
  1290.         ConOutputUpdate();
  1291.     }
  1292.  
  1293.     ForegroundPen    = CursorBackup.FgPen;
  1294.     BackgroundPen    = CursorBackup.BgPen;
  1295.     Attributes        = CursorBackup.Attributes;
  1296.     CursorX            = CursorBackup.CursorX;
  1297.     CursorY            = CursorBackup.CursorY;
  1298.  
  1299.     UpdatePens();
  1300.  
  1301.     ConFontScaleUpdate();
  1302.  
  1303.     RepositionCursor();
  1304. }
  1305.  
  1306.     /* ScaleFont(STRPTR Buffer):
  1307.      *
  1308.      *    Select a new font scale.
  1309.      */
  1310.  
  1311. VOID
  1312. ScaleFont(STRPTR Buffer)
  1313. {
  1314.     if(!Config->EmulationConfig->FontLocked)
  1315.     {
  1316.         LONG NewScale,Scale;
  1317.  
  1318.         Scale = RasterAttr[CursorY];
  1319.  
  1320.         NewScale = Scale;
  1321.  
  1322.         switch(LastChar(Buffer))
  1323.         {
  1324.             case '3':
  1325.  
  1326.                 NewScale = SCALE_ATTR_TOP2X;
  1327.  
  1328.                 break;
  1329.  
  1330.             case '4':
  1331.  
  1332.                 NewScale = SCALE_ATTR_BOT2X;
  1333.  
  1334.                 break;
  1335.  
  1336.             case '5':
  1337.  
  1338.                 NewScale = SCALE_NORMAL;
  1339.  
  1340.                 break;
  1341.  
  1342.             case '6':
  1343.  
  1344.                 NewScale = SCALE_ATTR_2X;
  1345.  
  1346.                 break;
  1347.         }
  1348.  
  1349.         if(Scale != NewScale)
  1350.         {
  1351.             LONG RightMargin,CursorXSave;
  1352.             UBYTE *RasterPtr;
  1353.  
  1354.             RasterPtr    = &Raster[CursorY * RasterWidth];
  1355.             RightMargin    = LastColumn + 1;
  1356.             CursorXSave    = CursorX;
  1357.  
  1358.             if(NewScale != SCALE_ATTR_NORMAL)
  1359.             {
  1360.                     /* Twice the normal character width */
  1361.  
  1362.                 if(CurrentCharWidth == SCALE_NORMAL)
  1363.                     RightMargin /= 2;
  1364.             }
  1365.             else
  1366.             {
  1367.                     /* Half the normal character width */
  1368.  
  1369.                 if(CurrentCharWidth != SCALE_NORMAL)
  1370.                     RightMargin *= 2;
  1371.             }
  1372.  
  1373.             RasterAttr[CursorY] = NewScale;
  1374.  
  1375.             RethinkRasterLimit();
  1376.  
  1377.             ConFontScaleUpdate();
  1378.  
  1379.             if(FontScalingRequired)
  1380.             {
  1381.                 CursorX = 0;
  1382.  
  1383.                 PrintScaled(RasterPtr,RightMargin,NewScale);
  1384.             }
  1385.             else
  1386.                 PlaceText(RPort,WindowLeft,WindowTop + MUL_Y(CursorY),RasterPtr,RightMargin);
  1387.  
  1388.             if(CursorXSave >= RightMargin)
  1389.                 CursorX = RightMargin - 1;
  1390.             else
  1391.                 CursorX = CursorXSave;
  1392.         }
  1393.  
  1394.         RepositionCursor();
  1395.     }
  1396. }
  1397.  
  1398.     /* AlignmentTest():
  1399.      *
  1400.      *    Perform screen alignment test, fill the screen with `E's.
  1401.      */
  1402.  
  1403. VOID
  1404. AlignmentTest()
  1405. {
  1406.     STRPTR Buffer;
  1407.  
  1408.     if(Buffer = AllocVecPooled(LastColumn + 1,MEMF_ANY))
  1409.     {
  1410.         LONG i;
  1411.  
  1412.         memset(Buffer,'E',LastColumn + 1);
  1413.  
  1414.         EraseScreen("2");
  1415.  
  1416.         if(FontScalingRequired)
  1417.         {
  1418.             for(i = 0 ; i <= LastLine ; i++)
  1419.             {
  1420.                 CursorX = 0;
  1421.                 CursorY = i;
  1422.  
  1423.                 RasterAttr[i] = SCALE_ATTR_NORMAL;
  1424.  
  1425.                 RasterPutString(Buffer,LastColumn + 1);
  1426.                 ScrollLinePutString(LastColumn + 1);
  1427.  
  1428.                 Move(RPort,WindowLeft,WindowTop + MUL_Y(i) + TextFontBase);
  1429.                 PrintScaled(Buffer,LastColumn + 1,SCALE_ATTR_NORMAL);
  1430.             }
  1431.         }
  1432.         else
  1433.         {
  1434.             for(i = 0 ; i <= LastLine ; i++)
  1435.             {
  1436.                 CursorX = 0;
  1437.                 CursorY = i;
  1438.  
  1439.                 RasterPutString(Buffer,LastColumn + 1);
  1440.                 ScrollLinePutString(LastColumn + 1);
  1441.  
  1442.                 PlaceText(RPort,WindowLeft,WindowTop + MUL_Y(i),Buffer,LastColumn + 1);
  1443.             }
  1444.         }
  1445.  
  1446.         CursorX = CursorY = 0;
  1447.  
  1448.         RethinkRasterLimit();
  1449.  
  1450.         RepositionCursor();
  1451.  
  1452.         FreeVecPooled(Buffer);
  1453.  
  1454.         ConFontScaleUpdate();
  1455.     }
  1456. }
  1457.  
  1458.     /* SetTab():
  1459.      *
  1460.      *    Set a tabulator stop at the current position.
  1461.      */
  1462.  
  1463. VOID
  1464. SetTab()
  1465. {
  1466.     if(CursorX < TabStopMax)
  1467.         TabStops[CursorX] = TRUE;
  1468. }
  1469.  
  1470.     /* RequestTerminal(STRPTR Buffer):
  1471.      *
  1472.      *    Return the current terminal position.
  1473.      */
  1474.  
  1475. VOID
  1476. RequestTerminal(STRPTR Buffer)
  1477. {
  1478.     STRPTR String;
  1479.  
  1480.     String = NULL;
  1481.  
  1482.     DB(kprintf("|%s|\n",Buffer));
  1483.  
  1484.     switch(Buffer[0])
  1485.     {
  1486.             /* Make ourselves known as a VT200
  1487.              * terminal.
  1488.              */
  1489.  
  1490.         case '[':
  1491.  
  1492.             if(Buffer[1] != '>')
  1493.             {
  1494.                 switch(Config->EmulationConfig->TerminalType)
  1495.                 {
  1496.                     case TERMINAL_VT100:
  1497.                     case TERMINAL_VT101:
  1498.  
  1499.                         String = "\033[?1;0c";    /* Vanilla VT100 */
  1500.                         break;
  1501.  
  1502.                     case TERMINAL_VT102:
  1503.  
  1504.                         String = "\033[?6c";
  1505.                         break;
  1506.  
  1507.                     case TERMINAL_VT200:
  1508.  
  1509.                         String = "\233?62;1;2;6;7;8;9c";
  1510.                         break;
  1511.                 }
  1512.             }
  1513.             else
  1514.                 String = "\233>1;10;0c";    /* Let's hope this command will never get called when responding in VT10x mode */
  1515.  
  1516.             break;
  1517.  
  1518.             /* This is an old VT52 status request type,
  1519.              * we will identify ourselves as a VT100
  1520.              * terminal
  1521.              */
  1522.  
  1523.         case 'Z':
  1524.  
  1525.             switch(Config->EmulationConfig->TerminalType)
  1526.             {
  1527.                 case TERMINAL_VT100:
  1528.  
  1529.                     String = "\033/Z";
  1530.                     break;
  1531.  
  1532.                 case TERMINAL_VT101:
  1533.  
  1534.                     String = "\033[?1;0c";
  1535.                     break;
  1536.  
  1537.                 case TERMINAL_VT102:
  1538.  
  1539.                     String = "\033[?6c";
  1540.                     break;
  1541.  
  1542.                 case TERMINAL_VT200:
  1543.  
  1544.                     String = "\233?62;1;2;6;7;8;9c";
  1545.                     break;
  1546.             }
  1547.  
  1548.             break;
  1549.     }
  1550.  
  1551.     DB(kprintf("out |%s|\n",String ? String+1 : "«NULL»"));
  1552.  
  1553.     if(String)
  1554.         EmulationSerWrite(String,-1);
  1555. }
  1556.  
  1557.     /* RequestTerminalParams(STRPTR Buffer):
  1558.      *
  1559.      *    Well, actually I don't really know what this routine actually
  1560.      *    does. I copied the parameters from the vttest program.
  1561.      */
  1562.  
  1563. VOID
  1564. RequestTerminalParams(STRPTR Buffer)
  1565. {
  1566.     STATIC WORD ParityTable[][2] =
  1567.     {
  1568.         PARITY_NONE,    1,
  1569.         PARITY_ODD,        4,
  1570.         PARITY_EVEN,    5,
  1571.         -1,                1
  1572.     };
  1573.  
  1574.     STATIC WORD SpeedTable[][2] =
  1575.     {
  1576.         50,        0,
  1577.         75,        8,
  1578.         110,    16,
  1579.         132,    24,
  1580.         150,    32,
  1581.         200,    40,
  1582.         300,    48,
  1583.         600,    56,
  1584.         1200,    64,
  1585.         1800,    72,
  1586.         2000,    80,
  1587.         2400,    88,
  1588.         3600,    96,
  1589.         4800,    104,
  1590.         9600,    112,
  1591.         19200,    120,
  1592.         -1
  1593.     };
  1594.  
  1595.     UBYTE LocalBuffer[40];
  1596.     STRPTR String;
  1597.     WORD Value;
  1598.     LONG Parity;
  1599.     LONG Bits;
  1600.     LONG Speed;
  1601.     LONG Delta,d;
  1602.     LONG i;
  1603.  
  1604.     DB(kprintf("|%s|\n",Buffer));
  1605.  
  1606.     ReadValue(Buffer,&Value);
  1607.  
  1608.     switch(Value)
  1609.     {
  1610.         case 1:
  1611.  
  1612.             String = "\033[3x";
  1613.             break;
  1614.  
  1615.         default:
  1616.  
  1617.             for(i = 0 ; ; i++)
  1618.             {
  1619.                 if(ParityTable[i][0] == -1 || ParityTable[i][0] == Config->SerialConfig->Parity)
  1620.                 {
  1621.                     Parity = ParityTable[i][1];
  1622.                     break;
  1623.                 }
  1624.             }
  1625.  
  1626.             if(Config->SerialConfig->BitsPerChar == 8)
  1627.                 Bits = 1;
  1628.             else
  1629.                 Bits = 2;
  1630.  
  1631.             Delta = -1;
  1632.  
  1633.             for(i = 0 ; SpeedTable[i][0] != -1 ; i++)
  1634.             {
  1635.                 if((d = SpeedTable[i][0] - Config->SerialConfig->BaudRate) < 0)
  1636.                     d = (-d);
  1637.  
  1638.                 if(Delta == -1 || d < Delta)
  1639.                 {
  1640.                     Speed = SpeedTable[i][1];
  1641.                     Delta = d;
  1642.                 }
  1643.             }
  1644.  
  1645.             LimitedSPrintf(sizeof(LocalBuffer),String = LocalBuffer,"\033[2;%ld;%ld;%ld;%ld;1;0x",Parity,Bits,Speed,Speed);
  1646.             break;
  1647.     }
  1648.  
  1649.     DB(kprintf("out |%s|\n",String ? String+1 : "«NULL»"));
  1650.  
  1651.     if(String)
  1652.         EmulationSerWrite(String,-1);
  1653. }
  1654.  
  1655.     /* SoftReset():
  1656.      *
  1657.      *    Plain and simple: reset the text rendering colours, style and the
  1658.      *    font being used. This works similar to the Reset() call which
  1659.      *    also clears the screen.
  1660.      */
  1661.  
  1662. VOID
  1663. SoftReset()
  1664. {
  1665.     ObtainSemaphore(&TerminalSemaphore);
  1666.  
  1667.         /* Are we running on an external emulation? */
  1668.  
  1669.     if(XEmulatorBase && Config->TerminalConfig->EmulationMode == EMULATION_EXTERNAL)
  1670.     {
  1671.         XEmulatorResetTextStyles(XEM_IO);
  1672.         XEmulatorResetCharset(XEM_IO);
  1673.     }
  1674.     else
  1675.     {
  1676.         if(!Config->EmulationConfig->FontLocked)
  1677.             CurrentCharWidth = SCALE_NORMAL;
  1678.  
  1679.             /* Reset the text rendering colours. */
  1680.  
  1681.         if(!Config->EmulationConfig->LockColour)
  1682.         {
  1683.             if(Config->ScreenConfig->ColourMode == COLOUR_SIXTEEN)    /* Special case */
  1684.                 ForegroundPen = 7;
  1685.             else
  1686.                 ForegroundPen = GetPenIndex(SafeTextPen);
  1687.  
  1688.             BackgroundPen = 0;
  1689.         }
  1690.  
  1691.         if(StyleType != FS_NORMAL && !Config->EmulationConfig->LockStyle)
  1692.             StyleType = FS_NORMAL;
  1693.  
  1694.         ConFontScaleUpdate();
  1695.  
  1696.         UpdatePens();
  1697.  
  1698.         CurrentFont = TextFont;
  1699.  
  1700.         SetFont(RPort,CurrentFont);
  1701.  
  1702.         ConOutputUpdate();
  1703.  
  1704.         CursorBackupValid = FALSE;
  1705.  
  1706.         VT52_Mode = FALSE;
  1707.     }
  1708.  
  1709.     ReleaseSemaphore(&TerminalSemaphore);
  1710. }
  1711.  
  1712.     /* Reset():
  1713.      *
  1714.      *    Reset terminal to initial state.
  1715.      */
  1716.  
  1717. VOID
  1718. Reset()
  1719. {
  1720.     LONG MaxColumns,MaxLines,Columns,Lines,i;
  1721.  
  1722.     ObtainSemaphore(&TerminalSemaphore);
  1723.  
  1724.     CursorEnabled = CursorInvisible = FALSE;
  1725.  
  1726.     if(Window->Flags & WFLG_WINDOWACTIVE)
  1727.         CursorGhosted = FALSE;
  1728.     else
  1729.         CursorGhosted = TRUE;
  1730.  
  1731.         /* Determine window inner dimensions and top/left edge offsets. */
  1732.  
  1733.     UpdateTerminalLimits();
  1734.  
  1735.     MaxColumns    = WindowWidth / TextFontWidth;
  1736.     MaxLines    = WindowHeight / TextFontHeight;
  1737.  
  1738.         /* Set up the new screen width. */
  1739.  
  1740.     if(Config->TerminalConfig->NumColumns < 20 || Config->TerminalConfig->AutoSize)
  1741.         Columns = MaxColumns;
  1742.     else
  1743.         Columns = Config->TerminalConfig->NumColumns;
  1744.  
  1745.         /* Set up the new screen height. */
  1746.  
  1747.     if(Config->TerminalConfig->NumLines < 20 || Config->TerminalConfig->AutoSize)
  1748.         Lines = MaxLines;
  1749.     else
  1750.         Lines = Config->TerminalConfig->NumLines;
  1751.  
  1752.         /* More columns than we will be able to display? */
  1753.  
  1754.     if(Columns > MaxColumns)
  1755.         Columns = MaxColumns;
  1756.  
  1757.         /* More lines than we will be able to display? */
  1758.  
  1759.     if(Lines > MaxLines)
  1760.         Lines = MaxLines;
  1761.  
  1762.         /* Set up the central data. */
  1763.  
  1764.     LastColumn    = Columns - 1;
  1765.     LastLine    = Lines - 1;
  1766.     LastPixel    = MUL_X(Columns) - 1;
  1767.  
  1768.     for(i = 0 ; i <= LastLine ; i++)
  1769.         RasterAttr[i] = SCALE_ATTR_NORMAL;
  1770.  
  1771.     memset(TabStops,FALSE,TabStopMax);
  1772.  
  1773.     for(i = 8 ; i < TabStopMax ; i += 8)
  1774.         TabStops[i] = TRUE;
  1775.  
  1776.     CharMode[0] = TABLE_ASCII;
  1777.     CharMode[1] = TABLE_GFX;
  1778.  
  1779.     Charset = 0;
  1780.  
  1781.     SetAPen(RPort,MappedPens[0][PenTable[0]]);
  1782.  
  1783.     SetMask(RPort,DepthMask);
  1784.  
  1785.     FillBox(RPort,WindowLeft,WindowTop,WindowWidth,WindowHeight);
  1786.  
  1787.     ScrollLineEraseScreen(2);
  1788.  
  1789.     RasterEraseScreen(2);
  1790.  
  1791.     if(!Config->EmulationConfig->LockColour)
  1792.     {
  1793.         if(Config->ScreenConfig->ColourMode == COLOUR_SIXTEEN)    /* Special case */
  1794.             ForegroundPen = 7;
  1795.         else
  1796.             ForegroundPen = GetPenIndex(SafeTextPen);
  1797.  
  1798.         BackgroundPen = 0;
  1799.     }
  1800.  
  1801.     if(StyleType != FS_NORMAL && !Config->EmulationConfig->LockStyle)
  1802.         StyleType = FS_NORMAL;
  1803.  
  1804.     UpdatePens();
  1805.  
  1806.     CurrentFont = TextFont;
  1807.  
  1808.     SetFont(RPort,CurrentFont);
  1809.  
  1810.     ConOutputUpdate();
  1811.  
  1812.     UseRegion = FALSE;
  1813.     RegionSet = FALSE;
  1814.  
  1815.     DB(kprintf("scroll region turned off\n"));
  1816.  
  1817.     if(!Config->EmulationConfig->CursorLocked)
  1818.         Config->EmulationConfig->CursorMode = KEYMODE_STANDARD;
  1819.  
  1820.     if(!Config->EmulationConfig->KeysLocked)
  1821.         Config->EmulationConfig->NumericMode = KEYMODE_STANDARD;
  1822.  
  1823.     Config->EmulationConfig->NewLineMode    = FALSE;
  1824.     Config->EmulationConfig->InsertMode        = FALSE;
  1825.     Config->EmulationConfig->ScrollMode        = SCROLL_JUMP;
  1826.  
  1827.     if(!Config->EmulationConfig->LockWrapping)
  1828.         Config->EmulationConfig->LineWrap = TRUE;
  1829.  
  1830.     if(!Config->EmulationConfig->FontLocked)
  1831.         CurrentCharWidth = SCALE_NORMAL;
  1832.  
  1833.     if(!Config->EmulationConfig->LockStyle)
  1834.         Attributes = 0;
  1835.  
  1836.     VT52_Mode = FALSE;
  1837.  
  1838.     Top            = 0;
  1839.     Bottom        = LastLine;
  1840.     CursorX        = 0;
  1841.     CursorY        = 0;
  1842.  
  1843.     CursorBackup.Charset        = Charset;
  1844.     CursorBackup.Attributes        = Attributes;
  1845.     CursorBackup.CursorX        = CursorX;
  1846.     CursorBackup.CursorY        = CursorY;
  1847.     CursorBackup.Style            = StyleType;
  1848.     CursorBackup.FgPen            = ForegroundPen;
  1849.     CursorBackup.BgPen            = BackgroundPen;
  1850.     CursorBackup.CurrentFont    = CurrentFont;
  1851.     CursorBackup.CharMode[0]    = CharMode[0];
  1852.     CursorBackup.CharMode[1]    = CharMode[1];
  1853.  
  1854.     CursorBackupValid = FALSE;
  1855.  
  1856.     ConFontScaleUpdate();
  1857.  
  1858.     RepositionCursor();
  1859.  
  1860.     ReleaseSemaphore(&TerminalSemaphore);
  1861. }
  1862.  
  1863.     /* PrinterController(STRPTR Buffer):
  1864.      *
  1865.      *    Controls various screen dump and capture functions.
  1866.      */
  1867.  
  1868. VOID
  1869. PrinterController(STRPTR Buffer)
  1870. {
  1871.     if(Config->EmulationConfig->PrinterEnabled)
  1872.     {
  1873.         switch(Buffer[1])
  1874.         {
  1875.             case 'i':    /* Print screen */
  1876.             case '0':
  1877.  
  1878.                 if(PrintFullScreen)
  1879.                     PrintRegion(0,LastLine + 1,PrintFormFeed);
  1880.                 else
  1881.                     PrintRegion(Top,Bottom + 1,PrintFormFeed);
  1882.  
  1883.                 break;
  1884.  
  1885.             case '5':    /* Turn on printer controller mode */
  1886.  
  1887.                 OpenPrinterCapture(TRUE);
  1888.                 break;
  1889.  
  1890.             case '4':    /* Turn off printer controller mode */
  1891.  
  1892.                 ClosePrinterCapture(FALSE);
  1893.                 break;
  1894.  
  1895.             case '?':
  1896.  
  1897.                 if(Buffer[2] == '1')    /* Print current line */
  1898.                     PrintRegion(CursorY,CursorY + 1,FALSE);
  1899.  
  1900.                 if(Buffer[2] == '5')    /* Turn on auto print mode */
  1901.                     OpenPrinterCapture(FALSE);
  1902.  
  1903.                 if(Buffer[2] == '4')    /* Turn off auto print mode */
  1904.                     ClosePrinterCapture(FALSE);
  1905.  
  1906.                 break;
  1907.         }
  1908.     }
  1909. }
  1910.  
  1911.     /* RequestInformation(STRPTR Buffer):
  1912.      *
  1913.      *    Request miscellaneous information (state & cursor position).
  1914.      */
  1915.  
  1916. VOID
  1917. RequestInformation(STRPTR Buffer)
  1918. {
  1919.     UBYTE LocalBuffer[40];
  1920.     WORD Value;
  1921.  
  1922.     ReadValue(Buffer,&Value);
  1923.  
  1924.     switch(Value)
  1925.     {
  1926.             /* Terminal status report, return code
  1927.              * for `no malfunction'.
  1928.              */
  1929.  
  1930.         case 5:
  1931.  
  1932.             EmulationSerWrite("\033[0n",-1);
  1933.             break;
  1934.  
  1935.             /* The origin is placed at 0/0 and the first
  1936.              * cursor position is 1/1. We'll have to add
  1937.              * 1 to our internal positions since our
  1938.              * universe has been shifted one field to the
  1939.              * left top corner.
  1940.              */
  1941.  
  1942.         case 6:
  1943.  
  1944.             LimitedSPrintf(sizeof(LocalBuffer),LocalBuffer,"\033[%ld;%ldR",CursorY + 1,CursorX + 1);
  1945.  
  1946.             EmulationSerWrite(LocalBuffer,-1);
  1947.  
  1948.             break;
  1949.  
  1950.             /* A VT200 command: request printer status.
  1951.              * We will return `the printer is ready' in
  1952.              * case the printer control commands are
  1953.              * enabled, else return `no printer connected'.
  1954.              */
  1955.  
  1956.         case 15:
  1957.  
  1958.             if(Config->EmulationConfig->PrinterEnabled)
  1959.                 EmulationSerWrite("\033[?10n",-1);
  1960.             else
  1961.                 EmulationSerWrite("\033[?11n",-1);
  1962.  
  1963.             break;
  1964.  
  1965.             /* VT200 command: request user defined
  1966.              * key status. We will return `user
  1967.              * defined keys are locked'.
  1968.              */
  1969.  
  1970.         case 25:
  1971.  
  1972.             EmulationSerWrite("\033[?21n",-1);
  1973.             break;
  1974.  
  1975.             /* Another VT200 command: request
  1976.              * keyboard language. We will return
  1977.              * `keyboard language unknown'.
  1978.              */
  1979.  
  1980.         case 26:
  1981.  
  1982.             EmulationSerWrite("\033[?27;0n",-1);
  1983.             break;
  1984.     }
  1985. }
  1986.  
  1987.     /* SetSomething(STRPTR Buffer):
  1988.      *
  1989.      *    Set a terminal option.
  1990.      */
  1991.  
  1992. VOID
  1993. SetSomething(STRPTR Buffer)
  1994. {
  1995.     BOOL TurnOn;
  1996.     WORD Value;
  1997.     LONG Last;
  1998.  
  1999.     ReadValue(Buffer,&Value);
  2000.     Last = LastChar(Buffer);
  2001.  
  2002.     if(Buffer[1] == '?')
  2003.     {
  2004.         switch(Value)
  2005.         {
  2006.                 /* Set cursor keys applications mode. */
  2007.  
  2008.             case 1:
  2009.  
  2010.                     /* DECCKM */
  2011.  
  2012.                 if(!Config->EmulationConfig->CursorLocked)
  2013.                 {
  2014.                     if(Last == 'h')
  2015.                         Config->EmulationConfig->CursorMode = KEYMODE_APPLICATION;
  2016.  
  2017.                     if(Last == 'l')
  2018.                         Config->EmulationConfig->CursorMode = KEYMODE_STANDARD;
  2019.                 }
  2020.  
  2021.                 break;
  2022.  
  2023.                 /* ANSI/VT52 mode */
  2024.  
  2025.             case 2:
  2026.  
  2027.                     /* DECANM */
  2028.  
  2029.                 if(Last != 'h')
  2030.                     VT52_Mode = TRUE;
  2031.  
  2032.                 break;
  2033.  
  2034.                 /* Set line length (132 or 80). */
  2035.  
  2036.             case 3:
  2037.  
  2038.                     /* DECCOLM */
  2039.  
  2040.                 if(!Config->EmulationConfig->FontLocked)
  2041.                 {
  2042.                     if(CursorEnabled)
  2043.                     {
  2044.                         ClearCursor();
  2045.  
  2046.                         TurnOn = TRUE;
  2047.                     }
  2048.                     else
  2049.                         TurnOn = FALSE;
  2050.  
  2051.                     if(Last == 'h')
  2052.                     {
  2053.                         if(CurrentCharWidth != SCALE_HALF)
  2054.                         {
  2055.                             CursorX = CursorY = 0;
  2056.  
  2057.                             RepositionCursor();
  2058.  
  2059.                             BackupRender();
  2060.  
  2061.                             SetAPen(RPort,MappedPens[0][PenTable[0]]);
  2062.  
  2063.                             ScrollLineRectFillNoTabChange(RPort,0,0,LastPixel,MUL_Y(LastLine + 1) - 1);
  2064.  
  2065.                             ScrollLineEraseScreen(2);
  2066.  
  2067.                             RasterEraseScreen(2);
  2068.  
  2069.                             SaveConfig(Config,PrivateConfig);
  2070.  
  2071.                             CurrentCharWidth = SCALE_HALF;
  2072.  
  2073.                             BackupRender();
  2074.  
  2075.                             ScreenSizeStuff();
  2076.                         }
  2077.                     }
  2078.  
  2079.                     if(Last == 'l')
  2080.                     {
  2081.                         if(CurrentCharWidth != SCALE_NORMAL)
  2082.                         {
  2083.                             CursorX = CursorY = 0;
  2084.  
  2085.                             RepositionCursor();
  2086.  
  2087.                             BackupRender();
  2088.  
  2089.                             SetAPen(RPort,MappedPens[0][PenTable[0]]);
  2090.  
  2091.                             ScrollLineRectFillNoTabChange(RPort,0,0,LastPixel,MUL_Y(LastLine + 1) - 1);
  2092.  
  2093.                             ScrollLineEraseScreen(2);
  2094.  
  2095.                             RasterEraseScreen(2);
  2096.  
  2097.                             SaveConfig(Config,PrivateConfig);
  2098.  
  2099.                             CurrentCharWidth = SCALE_NORMAL;
  2100.  
  2101.                             BackupRender();
  2102.  
  2103.                             ScreenSizeStuff();
  2104.                         }
  2105.                     }
  2106.  
  2107.                     if(TurnOn)
  2108.                         DrawCursor();
  2109.                     else
  2110.                         ClearCursor();
  2111.                 }
  2112.  
  2113.                 break;
  2114.  
  2115.                 /* Set scroll mode (jump or smooth). */
  2116.  
  2117.             case 4:
  2118.  
  2119.                     /* DECSCLM */
  2120.  
  2121.                 if(Last == 'h')
  2122.                     Config->EmulationConfig->ScrollMode = SCROLL_SMOOTH;
  2123.  
  2124.                 if(Last == 'l')
  2125.                     Config->EmulationConfig->ScrollMode = SCROLL_JUMP;
  2126.  
  2127.                 break;
  2128.  
  2129.                 /* Reverse/normal screen. */
  2130.  
  2131.             case 5:
  2132.  
  2133.                     /* DECSCNM */
  2134.  
  2135.                 break;
  2136.  
  2137.                 /* Turn region on or off. */
  2138.  
  2139.             case 6:
  2140.  
  2141.                 if(Last == 'h')
  2142.                     UseRegion = TRUE;
  2143.  
  2144.                 if(Last == 'l')
  2145.                     UseRegion = FALSE;
  2146.  
  2147.                 DB(kprintf("scroll region = %ld\n",UseRegion));
  2148.  
  2149.                 break;
  2150.  
  2151.                 /* Turn character wrapping on or off. */
  2152.  
  2153.             case 7:
  2154.  
  2155.                     /* DECAWM */
  2156.  
  2157.                 if(!Config->EmulationConfig->LockWrapping)
  2158.                 {
  2159.                     if(Last == 'h')
  2160.                         Config->EmulationConfig->LineWrap = TRUE;
  2161.  
  2162.                     if(Last == 'l')
  2163.                         Config->EmulationConfig->LineWrap = FALSE;
  2164.                 }
  2165.  
  2166.                 break;
  2167.  
  2168.                 /* Turn auto repeat on or off. */
  2169.  
  2170.             case 8:
  2171.  
  2172.                     /* DECARM */
  2173.  
  2174.                 break;
  2175.  
  2176.                 /* Set 240/480 line mode. */
  2177.  
  2178.             case 9:
  2179.  
  2180.                 break;
  2181.  
  2182.                 /* Print form feed after `print screen command'. */
  2183.  
  2184.             case 18:
  2185.  
  2186.                     /* DECPFF */
  2187.  
  2188.                 if(Last == 'h')
  2189.                     PrintFormFeed = TRUE;
  2190.  
  2191.                 if(Last == 'l')
  2192.                     PrintFormFeed = FALSE;
  2193.  
  2194.                 break;
  2195.  
  2196.                 /* Print full screen or just region. */
  2197.  
  2198.             case 19:
  2199.  
  2200.                     /* DECPEX */
  2201.  
  2202.                 if(Last == 'h')
  2203.                     PrintFullScreen = TRUE;
  2204.  
  2205.                 if(Last == 'l')
  2206.                     PrintFullScreen = FALSE;
  2207.  
  2208.                 break;
  2209.  
  2210.                 /* Text cursor enable. */
  2211.  
  2212.             case 25:
  2213.  
  2214.                     /* DECTCEM */
  2215.  
  2216.                 TurnOn = CursorEnabled;
  2217.  
  2218.                 ClearCursor();
  2219.  
  2220.                 if(Last == 'h')
  2221.                     CursorInvisible = FALSE;
  2222.  
  2223.                 if(Last == 'l')
  2224.                     CursorInvisible = TRUE;
  2225.  
  2226.                 if(TurnOn)
  2227.                     DrawCursor();
  2228.  
  2229.                 break;
  2230.  
  2231.                 /* National/multinational character set. */
  2232.  
  2233.             case 42:
  2234.  
  2235.                     /* DECNRCM */
  2236.  
  2237.                 break;
  2238.         }
  2239.     }
  2240.     else
  2241.     {
  2242.         switch(Value)
  2243.         {
  2244.                 /* Keyboard action unlocked/locked. */
  2245.  
  2246.             case 2:
  2247.  
  2248.                     /* KAM */
  2249.  
  2250.                 break;
  2251.  
  2252.                 /* Insertion/replacement. */
  2253.  
  2254.             case 4:
  2255.  
  2256.                     /* IRM */
  2257.  
  2258.                 if(Last == 'h')
  2259.                     Config->EmulationConfig->InsertMode = TRUE;
  2260.  
  2261.                 if(Last == 'l')
  2262.                     Config->EmulationConfig->InsertMode = FALSE;
  2263.  
  2264.                 break;
  2265.  
  2266.                 /* Echo on/off. */
  2267.  
  2268.             case 12:
  2269.  
  2270.                     /* SRM */
  2271.  
  2272.                 if(Last == 'h')
  2273.                     Config->SerialConfig->Duplex = DUPLEX_FULL;
  2274.  
  2275.                 if(Last == 'l')
  2276.                     Config->SerialConfig->Duplex = DUPLEX_HALF;
  2277.  
  2278.                 break;
  2279.  
  2280.                 /* Line feed/new line. */
  2281.  
  2282.             case 20:
  2283.  
  2284.                     /* LNM */
  2285.  
  2286.                 if(Last == 'h')
  2287.                     Config->EmulationConfig->NewLineMode = TRUE;
  2288.  
  2289.                 if(Last == 'l')
  2290.                     Config->EmulationConfig->NewLineMode = FALSE;
  2291.  
  2292.                 break;
  2293.         }
  2294.     }
  2295. }
  2296.  
  2297.     /* NumericAppMode(STRPTR Buffer):
  2298.      *
  2299.      *    Set the numeric pad applications mode.
  2300.      */
  2301.  
  2302. VOID
  2303. NumericAppMode(STRPTR Buffer)
  2304. {
  2305.     if(!Config->EmulationConfig->KeysLocked)
  2306.     {
  2307.         if(*Buffer == '=')
  2308.             Config->EmulationConfig->NumericMode = KEYMODE_APPLICATION;
  2309.         else
  2310.         {
  2311.             if(*Buffer == '>')
  2312.                 Config->EmulationConfig->NumericMode = KEYMODE_STANDARD;
  2313.         }
  2314.     }
  2315. }
  2316.  
  2317.     /* MoveCursor(STRPTR Buffer):
  2318.      *
  2319.      *    Move the cursor in some direction and stop at
  2320.      *    top/bottom/margin if necessary.
  2321.      */
  2322.  
  2323. VOID
  2324. MoveCursor(STRPTR Buffer)
  2325. {
  2326.     BOOL InRegion;
  2327.     BOOL GoDown;
  2328.     WORD Value;
  2329.     LONG Hit;
  2330.  
  2331.     InRegion    = TRUE;
  2332.     GoDown        = FALSE;
  2333.  
  2334.     ReadValue(Buffer,&Value);
  2335.  
  2336.     if(Value < 1)
  2337.         Value = 1;
  2338.  
  2339.     switch(LastChar(Buffer))
  2340.     {
  2341.             /* Move cursor Up value lines */
  2342.  
  2343.         case 'A':
  2344.  
  2345.             Hit = 0;
  2346.  
  2347.             if(RegionSet)
  2348.             {
  2349.                 if(CursorY >= Top)
  2350.                     Hit = Top;
  2351.                 else
  2352.                     InRegion = FALSE;
  2353.             }
  2354.  
  2355.             CursorY -= Value;
  2356.  
  2357.             if(CursorY < Hit)
  2358.             {
  2359.                 Value = CursorY - Hit;
  2360.  
  2361.                 CursorY = Hit;
  2362.  
  2363.                 if(Config->EmulationConfig->CursorWrap && InRegion)
  2364.                     ScrollRegion(Value);
  2365.             }
  2366.  
  2367.             ConFontScaleUpdate();
  2368.  
  2369.             break;
  2370.  
  2371.             /* Move cursor Down value lines */
  2372.  
  2373.         case 'B':
  2374.  
  2375.             GoDown = TRUE;
  2376.             break;
  2377.  
  2378.             /* Move cursor Right value columns */
  2379.  
  2380.         case 'C':
  2381.  
  2382.             CursorX += Value;
  2383.  
  2384.             if(CursorX > LastPrintableColumn)
  2385.             {
  2386.                 if(Config->EmulationConfig->CursorWrap)
  2387.                 {
  2388.                     Value = CursorX / (LastPrintableColumn + 1);
  2389.  
  2390.                     CursorX    -= Value * (LastPrintableColumn + 1);
  2391.  
  2392.                     GoDown = TRUE;
  2393.                 }
  2394.                 else
  2395.                     CursorX = LastPrintableColumn;
  2396.             }
  2397.  
  2398.             break;
  2399.  
  2400.             /* Move cursor Left value columns */
  2401.  
  2402.         case 'D':
  2403.  
  2404.             CursorX -= Value;
  2405.  
  2406.             if(CursorX < 0)
  2407.             {
  2408.                 if(Config->EmulationConfig->CursorWrap)
  2409.                 {
  2410.                     Value     = CursorX / (LastPrintableColumn + 1);
  2411.                     CursorX    -= Value * (LastPrintableColumn + 1);
  2412.                     Value     = -Value;
  2413.  
  2414.                     GoDown = TRUE;
  2415.                 }
  2416.                 else
  2417.                     CursorX = 0;
  2418.             }
  2419.  
  2420.             break;
  2421.     }
  2422.  
  2423.         /* Scroll down? */
  2424.  
  2425.     if(GoDown)
  2426.     {
  2427.         Hit = LastLine;
  2428.  
  2429.         if(RegionSet)
  2430.         {
  2431.             if(CursorY <= Bottom)
  2432.                 Hit = Bottom;
  2433.             else
  2434.                 InRegion = FALSE;
  2435.         }
  2436.  
  2437.         CursorY += Value;
  2438.  
  2439.         if(CursorY > Hit)
  2440.         {
  2441.             Value = CursorY - Hit;
  2442.  
  2443.             CursorY = Hit;
  2444.  
  2445.             if(Config->EmulationConfig->CursorWrap && InRegion)
  2446.                 ScrollRegion(Value);
  2447.         }
  2448.  
  2449.         ConFontScaleUpdate();
  2450.     }
  2451.  
  2452.     if(CursorX > LastPrintableColumn)
  2453.         CursorX = LastPrintableColumn;
  2454.  
  2455.     RepositionCursor();
  2456. }
  2457.  
  2458.     /* MoveColumn(STRPTR Buffer):
  2459.      *
  2460.      *    Move the cursor to a certain column.
  2461.      */
  2462.  
  2463. VOID
  2464. MoveColumn(STRPTR Buffer)
  2465. {
  2466.     WORD Value;
  2467.  
  2468.     ReadValue(Buffer,&Value);
  2469.  
  2470.     if(Value < 1)
  2471.         Value = 1;
  2472.  
  2473.     CursorX = Value - 1;
  2474.  
  2475.     if(CursorX < 0)
  2476.         CursorX = 0;
  2477.  
  2478.     if(CursorX > LastPrintableColumn)
  2479.         CursorX = LastPrintableColumn;
  2480.  
  2481.     RepositionCursor();
  2482. }
  2483.  
  2484.     /* EraseLine(STRPTR Buffer):
  2485.      *
  2486.      *    Erase a line on the display.
  2487.      */
  2488.  
  2489. VOID
  2490. EraseLine(STRPTR Buffer)
  2491. {
  2492.     WORD Value;
  2493.     LONG Width;
  2494.  
  2495.     Width = GetFontWidth();
  2496.  
  2497.     if(*Buffer == '?')
  2498.         Buffer++;
  2499.  
  2500.     ReadValue(Buffer,&Value);
  2501.  
  2502.     BackupRender();
  2503.  
  2504.     switch(Value)
  2505.     {
  2506.         case 1:
  2507.  
  2508.             if(CursorX)
  2509.                 ScrollLineRectFillNoTabChange(RPort,0,MUL_Y(CursorY),CursorX * Width - 1,MUL_Y(CursorY + 1) - 1);
  2510.  
  2511.             break;
  2512.  
  2513.         case 2:
  2514.  
  2515.             ScrollLineRectFillNoTabChange(RPort,0,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1);
  2516.             break;
  2517.  
  2518.         default:
  2519.  
  2520.             ScrollLineRectFillNoTabChange(RPort,CursorX * Width,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1);
  2521.             break;
  2522.     }
  2523.  
  2524.     ScrollLineEraseLine(Value);
  2525.  
  2526.     RasterEraseLine(Value);
  2527.  
  2528.     BackupRender();
  2529. }
  2530.  
  2531.     /* EraseScreen(STRPTR Buffer):
  2532.      *
  2533.      *    Erase parts of the screen.
  2534.      */
  2535.  
  2536. VOID
  2537. EraseScreen(STRPTR Buffer)
  2538. {
  2539.     WORD Value;
  2540.     LONG Width;
  2541.  
  2542.     Width = GetFontWidth();
  2543.  
  2544.     if(*Buffer == '?')
  2545.         Buffer++;
  2546.  
  2547.     ReadValue(Buffer,&Value);
  2548.  
  2549.     BackupRender();
  2550.  
  2551.     switch(Value)
  2552.     {
  2553.         case 1:
  2554.  
  2555.             if(CursorY)
  2556.                 ScrollLineRectFillNoTabChange(RPort,0,0,LastPixel,MUL_Y(CursorY) - 1);
  2557.  
  2558.             if(CursorX)
  2559.                 ScrollLineRectFillNoTabChange(RPort,0,MUL_Y(CursorY),CursorX * Width - 1,MUL_Y(CursorY + 1) - 1);
  2560.  
  2561.             break;
  2562.  
  2563.         case 2:
  2564.  
  2565.             ScrollLineRectFillNoTabChange(RPort,0,0,LastPixel,MUL_Y(LastLine + 1) - 1);
  2566.  
  2567.             if(Config->EmulationConfig->CLSResetsCursor)
  2568.                 CursorX = CursorY = 0;
  2569.  
  2570.             break;
  2571.  
  2572.         default:
  2573.  
  2574.             ScrollLineRectFillNoTabChange(RPort,CursorX * Width,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1);
  2575.  
  2576.             if(CursorY != LastLine)
  2577.                 ScrollLineRectFillNoTabChange(RPort,0,MUL_Y(CursorY + 1),LastPixel,MUL_Y(LastLine + 1) - 1);
  2578.  
  2579.             break;
  2580.     }
  2581.  
  2582.     ScrollLineEraseScreen(Value);
  2583.  
  2584.     RasterEraseScreen(Value);
  2585.  
  2586.     BackupRender();
  2587. }
  2588.  
  2589.     /* EraseCharacters(STRPTR Buffer):
  2590.      *
  2591.      *    Erase a number of characters.
  2592.      */
  2593.  
  2594. VOID
  2595. EraseCharacters(STRPTR Buffer)
  2596. {
  2597.     WORD Value;
  2598.     LONG Width;
  2599.  
  2600.     Width = GetFontWidth();
  2601.  
  2602.     if(*Buffer == '?')
  2603.         Buffer++;
  2604.  
  2605.     ReadValue(Buffer,&Value);
  2606.  
  2607.     BackupRender();
  2608.  
  2609.     if(Value < 1)
  2610.         Value = 1;
  2611.  
  2612.     if(Value > LastPrintableColumn)
  2613.         Value = LastPrintableColumn;
  2614.  
  2615.     RasterEraseCharacters(Value);
  2616.  
  2617.     ScrollLineRasterNoTabChange(RPort,Value * Width,0,CursorX * Width,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1,FALSE);
  2618.  
  2619.     ScrollLineEraseCharacters(Value);
  2620.  
  2621.     BackupRender();
  2622. }
  2623.  
  2624.     /* InsertCharacters(STRPTR Buffer):
  2625.      *
  2626.      *    Insert a number of characters.
  2627.      */
  2628.  
  2629. VOID
  2630. InsertCharacters(STRPTR Buffer)
  2631. {
  2632.     WORD Value;
  2633.     LONG Width;
  2634.  
  2635.     Width = GetFontWidth();
  2636.  
  2637.     ReadValue(Buffer,&Value);
  2638.  
  2639.     BackupRender();
  2640.  
  2641.     if(Value < 1)
  2642.         Value = 1;
  2643.  
  2644.     if(CursorX + Value > LastPrintableColumn)
  2645.         Value = LastPrintableColumn - CursorX;
  2646.  
  2647.     if(Value > 0)
  2648.     {
  2649.         RasterShiftChar(Value);
  2650.  
  2651.         ScrollLineRasterNoTabChange(RPort,-Value * Width,0,CursorX * Width,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1,FALSE);
  2652.  
  2653.         ScrollLineShiftChar(Value);
  2654.     }
  2655.  
  2656.     BackupRender();
  2657. }
  2658.  
  2659.     /* InsertLine(STRPTR Buffer):
  2660.      *
  2661.      *    Insert a number of lines and scroll the rest of the
  2662.      *    display down.
  2663.      */
  2664.  
  2665. VOID
  2666. InsertLine(STRPTR Buffer)
  2667. {
  2668.     LONG RegionBottom,RegionTop,TheTop;
  2669.     WORD Value;
  2670.  
  2671.     TheTop = CursorY;
  2672.  
  2673.     ReadValue(Buffer,&Value);
  2674.  
  2675.     BackupRender();
  2676.  
  2677.     SetAPen(RPort,MappedPens[0][PenTable[0]]);
  2678.  
  2679.     if(Value < 1)
  2680.         Value = 1;
  2681.  
  2682.     if(RegionSet)
  2683.     {
  2684.         RegionTop        = Top;
  2685.         RegionBottom    = Bottom + 1;
  2686.     }
  2687.     else
  2688.     {
  2689.         RegionTop        = 0;
  2690.         RegionBottom    = LastLine + 1;
  2691.     }
  2692.  
  2693.     if(TheTop < RegionTop)
  2694.         TheTop = RegionTop;
  2695.  
  2696.     if(TheTop + Value > RegionBottom)
  2697.         Value = RegionBottom - TheTop;
  2698.  
  2699.     if(Value > 0)
  2700.     {
  2701.         RasterInsertLine(Value,TheTop);
  2702.  
  2703.         ScrollLineRaster(RPort,0,-MUL_Y(Value),0,MUL_Y(TheTop),LastPixel,MUL_Y(RegionBottom) - 1,FALSE);
  2704.     }
  2705.  
  2706.     BackupRender();
  2707. }
  2708.  
  2709.     /* ClearLine(STRPTR Buffer):
  2710.      *
  2711.      *    Clear a number of lines and scroll up the ones below it.
  2712.      */
  2713.  
  2714. VOID
  2715. ClearLine(STRPTR Buffer)
  2716. {
  2717.     LONG RegionBottom,RegionTop,TheTop;
  2718.     WORD Value;
  2719.  
  2720.     TheTop = CursorY;
  2721.  
  2722.     ReadValue(Buffer,&Value);
  2723.  
  2724.     BackupRender();
  2725.  
  2726.     SetAPen(RPort,MappedPens[0][PenTable[0]]);
  2727.  
  2728.     if(Value < 1)
  2729.         Value = 1;
  2730.  
  2731.     if(RegionSet)
  2732.     {
  2733.         RegionTop        = Top;
  2734.         RegionBottom    = Bottom + 1;
  2735.     }
  2736.     else
  2737.     {
  2738.         RegionTop        = 0;
  2739.         RegionBottom    = LastLine + 1;
  2740.     }
  2741.  
  2742.     if(TheTop < RegionTop)
  2743.         TheTop = RegionTop;
  2744.  
  2745.     if(TheTop + Value > RegionBottom)
  2746.         Value = RegionBottom - TheTop;
  2747.  
  2748.     if(Value > 0)
  2749.     {
  2750.         RasterClearLine(Value,TheTop);
  2751.  
  2752.         ScrollLineRaster(RPort,0,MUL_Y(Value),0,MUL_Y(TheTop),LastPixel,MUL_Y(RegionBottom) - 1,FALSE);
  2753.     }
  2754.  
  2755.     BackupRender();
  2756. }
  2757.  
  2758.     /* SetTabs(STRPTR Buffer):
  2759.      *
  2760.      *    Set the current tab stops.
  2761.      */
  2762.  
  2763. VOID
  2764. SetTabs(STRPTR Buffer)
  2765. {
  2766.     WORD Value;
  2767.  
  2768.     ReadValue(Buffer,&Value);
  2769.  
  2770.     if(Value < 1)
  2771.         Value = 0;
  2772.  
  2773.     switch(Value)
  2774.     {
  2775.         case 0:
  2776.  
  2777.             if(CursorX < TabStopMax)
  2778.                 TabStops[CursorX] = FALSE;
  2779.  
  2780.             break;
  2781.  
  2782.         case 3:
  2783.  
  2784.             memset(TabStops,FALSE,TabStopMax);
  2785.  
  2786.             break;
  2787.  
  2788.         default:
  2789.  
  2790.             break;
  2791.     }
  2792. }
  2793.  
  2794.     /* SetAbsolutePosition(STRPTR Buffer):
  2795.      *
  2796.      *    Move the cursor to a given location on the display,
  2797.      *    this routine ignores the current scroll region
  2798.      *    settings.
  2799.      */
  2800.  
  2801. VOID
  2802. SetAbsolutePosition(STRPTR Buffer)
  2803. {
  2804.     WORD Value;
  2805.  
  2806.     Buffer = ReadValue(Buffer,&Value);
  2807.  
  2808.     CursorY = 0;
  2809.     CursorX = 0;
  2810.  
  2811.     if(Value == -1)
  2812.         ConFontScaleUpdate();
  2813.     else
  2814.     {
  2815.             /* Our raster origin is 0/0 instead of 1/1. */
  2816.  
  2817.         if(Value)
  2818.             Value--;
  2819.  
  2820.         CursorY = Value;
  2821.  
  2822.         if(Buffer)
  2823.         {
  2824.             ReadValue(Buffer,&Value);
  2825.  
  2826.             if(Value > 0)
  2827.                 CursorX = Value - 1;
  2828.             else
  2829.                 CursorX = 0;
  2830.         }
  2831.  
  2832.             /* Truncate illegal positions. */
  2833.  
  2834.         if(CursorY > LastLine)
  2835.             CursorY = LastLine;
  2836.  
  2837.         ConFontScaleUpdate();
  2838.  
  2839.         if(CursorX > LastPrintableColumn)
  2840.             CursorX = LastPrintableColumn;
  2841.     }
  2842.  
  2843.     RepositionCursor();
  2844. }
  2845.  
  2846.     /* SetTopPosition(STRPTR Buffer):
  2847.      *
  2848.      *    Move the cursor to a given location on the display,
  2849.      *    this routine respects the current scroll region
  2850.      *    settings.
  2851.      */
  2852.  
  2853. VOID
  2854. SetTopPosition(STRPTR Buffer)
  2855. {
  2856.     WORD Value;
  2857.  
  2858.     Buffer = ReadValue(Buffer,&Value);
  2859.  
  2860.     if(UseRegion && RegionSet)
  2861.         CursorY = Top;
  2862.     else
  2863.         CursorY = 0;
  2864.  
  2865.     CursorX = 0;
  2866.  
  2867.     if(Value == -1)
  2868.         ConFontScaleUpdate();
  2869.     else
  2870.     {
  2871.             /* Our raster origin is 0/0 instead of 1/1. */
  2872.  
  2873.         if(Value)
  2874.             Value--;
  2875.  
  2876.         if(UseRegion && RegionSet)
  2877.             CursorY = Top + Value;
  2878.         else
  2879.             CursorY = Value;
  2880.  
  2881.         if(Buffer)
  2882.         {
  2883.             ReadValue(Buffer,&Value);
  2884.  
  2885.             if(Value > 0)
  2886.                 CursorX = Value - 1;
  2887.             else
  2888.                 CursorX = 0;
  2889.         }
  2890.  
  2891.             /* Truncate illegal positions. */
  2892.  
  2893.         if(CursorY > LastLine)
  2894.             CursorY = LastLine;
  2895.  
  2896.         ConFontScaleUpdate();
  2897.  
  2898.         if(CursorX > LastPrintableColumn)
  2899.             CursorX = LastPrintableColumn;
  2900.     }
  2901.  
  2902.     RepositionCursor();
  2903. }
  2904.  
  2905.     /* SetAttributes(STRPTR Buffer):
  2906.      *
  2907.      *    Set the current display rendering attributes.
  2908.      */
  2909.  
  2910. VOID
  2911. SetAttributes(STRPTR Buffer)
  2912. {
  2913.     WORD Value;
  2914.  
  2915.     do
  2916.     {
  2917.         Buffer = ReadValue(Buffer,&Value);
  2918.  
  2919.         if(Value == -1)
  2920.             Value = 0;
  2921.  
  2922.         switch(Value)
  2923.         {
  2924.             case 0:
  2925.  
  2926.                 if(!Config->EmulationConfig->LockColour)
  2927.                 {
  2928.                     if(Config->ScreenConfig->ColourMode == COLOUR_SIXTEEN)    /* Special case */
  2929.                         ForegroundPen = 7;
  2930.                     else
  2931.                         ForegroundPen = GetPenIndex(SafeTextPen);
  2932.  
  2933.                     BackgroundPen = 0;
  2934.                 }
  2935.  
  2936.                 if(!Config->EmulationConfig->LockStyle)
  2937.                     Attributes = 0;
  2938.  
  2939.                 break;
  2940.  
  2941.             case 1:
  2942.  
  2943.                 if(!Config->EmulationConfig->LockStyle)
  2944.                     Attributes |= ATTR_HIGHLIGHT;
  2945.  
  2946.                 break;
  2947.  
  2948.             case 4:
  2949.  
  2950.                 if(!Config->EmulationConfig->LockStyle)
  2951.                     Attributes |= ATTR_UNDERLINE;
  2952.  
  2953.                 break;
  2954.  
  2955.             case 5:
  2956.  
  2957.                 if(!Config->EmulationConfig->LockStyle)
  2958.                     Attributes |= ATTR_BLINK;
  2959.  
  2960.                 break;
  2961.  
  2962.             case 7:
  2963.  
  2964.                 if(!Config->EmulationConfig->LockStyle)
  2965.                     Attributes |= ATTR_INVERSE;
  2966.  
  2967.                 break;
  2968.  
  2969.             case 22:
  2970.  
  2971.                 if(!Config->EmulationConfig->LockStyle)
  2972.                     Attributes &= ~ATTR_HIGHLIGHT;
  2973.  
  2974.                 break;
  2975.  
  2976.             case 24:
  2977.  
  2978.                 if(!Config->EmulationConfig->LockStyle)
  2979.                     Attributes &= ~ATTR_UNDERLINE;
  2980.  
  2981.                 break;
  2982.  
  2983.             case 25:
  2984.  
  2985.                 if(!Config->EmulationConfig->LockStyle)
  2986.                     Attributes &= ~ATTR_BLINK;
  2987.  
  2988.                 break;
  2989.  
  2990.             case 27:
  2991.  
  2992.                 if(!Config->EmulationConfig->LockStyle)
  2993.                     Attributes &= ~ATTR_INVERSE;
  2994.  
  2995.                 break;
  2996.  
  2997.             default:
  2998.  
  2999.                 if(!Config->EmulationConfig->LockColour)
  3000.                 {
  3001.                     if(Value >= 30)
  3002.                     {
  3003.                         if(Value <= 37)
  3004.                             ForegroundPen = Value - 30;
  3005.                         else
  3006.                         {
  3007.                             if(Value >= 40 && Value <= 47)
  3008.                                 BackgroundPen = Value - 40;
  3009.                         }
  3010.                     }
  3011.                 }
  3012.  
  3013.                 break;
  3014.         }
  3015.     }
  3016.     while(Buffer);
  3017.  
  3018.     UpdatePens();
  3019.  
  3020.     RepositionCursor();
  3021. }
  3022.  
  3023.     /* SetRegion(STRPTR Buffer):
  3024.      *
  3025.      *    Set the current scroll region top and bottom.
  3026.      */
  3027.  
  3028. VOID
  3029. SetRegion(STRPTR Buffer)
  3030. {
  3031.     LONG NewTop,NewBottom;
  3032.     WORD Value;
  3033.  
  3034.     NewBottom = LastLine;
  3035.  
  3036.     Buffer = ReadValue(Buffer,&Value);
  3037.  
  3038.     if(!Value)
  3039.         Value = 1;
  3040.  
  3041.     if(Value > 0)
  3042.     {
  3043.         if(Buffer)
  3044.         {
  3045.             NewTop = Value - 1;
  3046.  
  3047.             ReadValue(Buffer,&Value);
  3048.  
  3049.             if(Value > 0)
  3050.                 NewBottom = Value - 1;
  3051.  
  3052.             if(NewBottom > LastLine)
  3053.                 NewBottom = LastLine;
  3054.  
  3055.             if(NewTop > LastLine)
  3056.                 NewTop = LastLine;
  3057.         }
  3058.         else
  3059.         {
  3060.             NewTop        = 0;
  3061.             NewBottom    = LastLine;
  3062.         }
  3063.     }
  3064.     else
  3065.     {
  3066.         NewTop        = 0;
  3067.         NewBottom    = LastLine;
  3068.     }
  3069.  
  3070.     if(NewTop < NewBottom)
  3071.     {
  3072.         if(NewTop != 0 || NewBottom != LastLine)
  3073.         {
  3074.             Top        = NewTop;
  3075.             Bottom    = NewBottom;
  3076.  
  3077.                 /* FIXME: not sure about this one */
  3078.  
  3079.             UseRegion = TRUE;
  3080.  
  3081.             RegionSet = TRUE;
  3082.         }
  3083.         else
  3084.             UseRegion = RegionSet = FALSE;
  3085.  
  3086.         DB(kprintf("scroll region %ld->%ld\n",Top,Bottom));
  3087.  
  3088.         ResetCursor();
  3089.     }
  3090.     else
  3091.         RegionSet = FALSE;
  3092. }
  3093.  
  3094.     /* ResetCursor():
  3095.      *
  3096.      *    Reset cursor to top of screen.
  3097.      */
  3098.  
  3099. VOID
  3100. ResetCursor()
  3101. {
  3102.     CursorX    = 0;
  3103.  
  3104.     if(UseRegion && RegionSet)
  3105.         CursorY = Top;
  3106.     else
  3107.         CursorY    = 0;
  3108.  
  3109.     ConFontScaleUpdate();
  3110.  
  3111.     RepositionCursor();
  3112. }
  3113.  
  3114.     /* MoveCursorUp(STRPTR Buffer):
  3115.      *
  3116.      *    Move the cursor up <n> lines, scroll the screen
  3117.      *    contents if necessary.
  3118.      */
  3119.  
  3120. VOID
  3121. MoveCursorUp(STRPTR Buffer)
  3122. {
  3123.     WORD Value;
  3124.     LONG i;
  3125.  
  3126.     ReadValue(Buffer,&Value);
  3127.  
  3128.     if(Value < 1)
  3129.         Value = 1;
  3130.  
  3131.     for(i = 0 ; i < Value ; i++)
  3132.         CursorScrollUp();
  3133.  
  3134.     CursorX = 0;
  3135.  
  3136.     RepositionCursor();
  3137. }
  3138.  
  3139.     /* MoveCursorDown(STRPTR Buffer):
  3140.      *
  3141.      *    Move the cursor down <n> lines, scroll the screen
  3142.      *    contents if necessary.
  3143.      */
  3144.  
  3145. VOID
  3146. MoveCursorDown(STRPTR Buffer)
  3147. {
  3148.     WORD Value;
  3149.     LONG i;
  3150.  
  3151.     ReadValue(Buffer,&Value);
  3152.  
  3153.     if(Value < 1)
  3154.         Value = 1;
  3155.  
  3156.     for(i = 0 ; i < Value ; i++)
  3157.         DownLine();
  3158.  
  3159.     CursorX = 0;
  3160.  
  3161.     RepositionCursor();
  3162. }
  3163.  
  3164.     /* VT52_CursorUp(STRPTR Buffer):
  3165.      *
  3166.      *    Move the cursor up one line.
  3167.      */
  3168.  
  3169. VOID
  3170. VT52_CursorUp(STRPTR UnusedBuffer)
  3171. {
  3172.     if(CursorY > 0)
  3173.     {
  3174.         CursorY--;
  3175.  
  3176.         RepositionCursor();
  3177.     }
  3178. }
  3179.  
  3180.     /* VT52_CursorDown(STRPTR Buffer):
  3181.      *
  3182.      *    Move the cursor down one line.
  3183.      */
  3184.  
  3185. VOID
  3186. VT52_CursorDown(STRPTR UnusedBuffer)
  3187. {
  3188.     if(CursorY < LastLine)
  3189.     {
  3190.         CursorY++;
  3191.  
  3192.         RepositionCursor();
  3193.     }
  3194. }
  3195.  
  3196.     /* VT52_CursorRight(STRPTR Buffer):
  3197.      *
  3198.      *    Move the cursor right one column.
  3199.      */
  3200.  
  3201. VOID
  3202. VT52_CursorRight(STRPTR UnusedBuffer)
  3203. {
  3204.     if(CursorX < LastColumn)
  3205.     {
  3206.         CursorX++;
  3207.  
  3208.         RepositionCursor();
  3209.     }
  3210. }
  3211.  
  3212.     /* VT52_CursorLeft(STRPTR Buffer):
  3213.      *
  3214.      *    Move the cursor left one column.
  3215.      */
  3216.  
  3217. VOID
  3218. VT52_CursorLeft(STRPTR UnusedBuffer)
  3219. {
  3220.         /* This command is shared by the VT220 emulation and */
  3221.         /* the VT52 mode. */
  3222.  
  3223.     if(VT52_Mode)
  3224.     {
  3225.         if(CursorX > 0)
  3226.         {
  3227.             CursorX--;
  3228.  
  3229.             RepositionCursor();
  3230.         }
  3231.     }
  3232.     else
  3233.         CursorScrollDown();    /* IND */
  3234. }
  3235.  
  3236.     /* VT52_CursorHome(STRPTR Buffer):
  3237.      *
  3238.      *    Move the cursor to the home position.
  3239.      */
  3240.  
  3241. VOID
  3242. VT52_CursorHome(STRPTR UnusedBuffer)
  3243. {
  3244.         /* This command is shared by the VT220 emulation and */
  3245.         /* the VT52 mode. */
  3246.  
  3247.     if(VT52_Mode)
  3248.     {
  3249.         CursorX = CursorY = 0;
  3250.  
  3251.         RepositionCursor();
  3252.     }
  3253.     else
  3254.         SetTab();
  3255. }
  3256.  
  3257.     /* VT52_RevLF(STRPTR Buffer):
  3258.      *
  3259.      *    Perform reverse line feed, i.e. move cursor up one line.
  3260.      */
  3261.  
  3262. VOID
  3263. VT52_RevLF(STRPTR UnusedBuffer)
  3264. {
  3265.     if(CursorY > 0)
  3266.     {
  3267.         CursorY--;
  3268.  
  3269.         RepositionCursor();
  3270.     }
  3271. }
  3272.  
  3273.     /* VT52_EraseEOS(STRPTR Buffer):
  3274.      *
  3275.      *    Erase till end of screen.
  3276.      */
  3277.  
  3278. VOID
  3279. VT52_EraseEOS(STRPTR UnusedBuffer)
  3280. {
  3281.     EraseScreen("0");
  3282. }
  3283.  
  3284.     /* VT52_EraseEOL(STRPTR Buffer):
  3285.      *
  3286.      *    Erase till end of line.
  3287.      */
  3288.  
  3289. VOID
  3290. VT52_EraseEOL(STRPTR UnusedBuffer)
  3291. {
  3292.     EraseLine("0");
  3293. }
  3294.  
  3295.     /* VT52_SetCursor(STRPTR Buffer):
  3296.      *
  3297.      *    Direct cursor address; move the cursor to a
  3298.      *    specific position.
  3299.      */
  3300.  
  3301. VOID
  3302. VT52_SetCursor(STRPTR Buffer)
  3303. {
  3304.     CursorX = Buffer[2] - ' ';
  3305.     CursorY = Buffer[1] - ' ';
  3306.  
  3307.     if(CursorX < 0)
  3308.         CursorX = 0;
  3309.     else
  3310.     {
  3311.         if(CursorX > LastColumn)
  3312.             CursorX = LastColumn;
  3313.     }
  3314.  
  3315.     if(CursorY < 0)
  3316.         CursorY = 0;
  3317.     else
  3318.     {
  3319.         if(CursorY > LastLine)
  3320.             CursorY = LastLine;
  3321.     }
  3322.  
  3323.     RepositionCursor();
  3324. }
  3325.  
  3326.     /* VT52_PrintOn(STRPTR Buffer):
  3327.      *
  3328.      *    Enter printer controller mode.
  3329.      */
  3330.  
  3331. VOID
  3332. VT52_PrintOn(STRPTR UnusedBuffer)
  3333. {
  3334.     OpenPrinterCapture(FALSE);
  3335. }
  3336.  
  3337.     /* VT52_PrintOff(STRPTR Buffer):
  3338.      *
  3339.      *    Exit printer controller mode.
  3340.      */
  3341.  
  3342. VOID
  3343. VT52_PrintOff(STRPTR UnusedBuffer)
  3344. {
  3345.     ClosePrinterCapture(FALSE);
  3346. }
  3347.  
  3348.     /* VT52_PrintScreen(STRPTR Buffer):
  3349.      *
  3350.      *    Print the entire screen.
  3351.      */
  3352.  
  3353. VOID
  3354. VT52_PrintScreen(STRPTR UnusedBuffer)
  3355. {
  3356.     if(Config->EmulationConfig->PrinterEnabled)
  3357.         PrintRegion(0,LastLine + 1,PrintFormFeed);
  3358. }
  3359.  
  3360.     /* VT52_PrintLine(STRPTR Buffer):
  3361.      *
  3362.      *    Print the line the cursor sits in.
  3363.      */
  3364.  
  3365. VOID
  3366. VT52_PrintLine(STRPTR UnusedBuffer)
  3367. {
  3368.     if(Config->EmulationConfig->PrinterEnabled)
  3369.         PrintRegion(CursorY,CursorY + 1,FALSE);
  3370. }
  3371.  
  3372.     /* VT52_EnterANSI(STRPTR Buffer):
  3373.      *
  3374.      *    Return to ANSI mode, or in other terms, change
  3375.      *    the behaviour of the "<ESC>H" and "<ESC>D" commands.
  3376.      */
  3377.  
  3378. VOID
  3379. VT52_EnterANSI(STRPTR UnusedBuffer)
  3380. {
  3381.     VT52_Mode = FALSE;
  3382. }
  3383.